diff --git a/.config/kysely.config.ts b/.config/kysely.config.ts new file mode 100644 index 00000000000..e61a3f275c9 --- /dev/null +++ b/.config/kysely.config.ts @@ -0,0 +1,13 @@ +import {defineConfig} from 'kysely-ctl' +import getKysely from '../packages/server/postgres/getKysely' + +export default defineConfig({ + kysely: getKysely(), + migrations: { + getMigrationPrefix: () => `${new Date().toISOString()}_`, + migrationFolder: './packages/server/postgres/migrations', + migrationTableSchema: 'public', + migrationTableName: '_migration', + migrationLockTableName: '_migrationLock' + } +}) diff --git a/.env.example b/.env.example index a3835e093d3..b18b4544081 100644 --- a/.env.example +++ b/.env.example @@ -79,8 +79,6 @@ REDIS_URL='redis://localhost:6379' # REDIS_TLS_KEY_FILE=./docker/stacks/development/redis/certs/redis.key # REDIS_TLS_CA_FILE=./docker/stacks/development/redis/certs/redisCA.crt # REDIS_TLS_REJECT_UNAUTHORIZED='false' -RETHINKDB_URL='rethinkdb://localhost:28015/actionDevelopment' -RETHINKDB_SSL='false' # DATADOG DD-Trace # https://ddtrace.readthedocs.io/en/stable/configuration.html diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9e8fa7ba7b3..ab98a11292e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,14 +4,13 @@ about: Create a report to help us improve title: '' labels: bug assignees: '' - --- ### Pre-submission instructions (remove me before creating an issue) - [ ] Decide is this is a bug or an enhancement request (if you can't decide, join the chat in [slack](http://slackin.parabol.co/) and ask in `#general`) - [ ] I've checked open (and closed!) issues and made sure that the issue doesn't already exist. -- [ ] I've updated RethinkDB, node, and npm to the latest version available +- [ ] I've updated node, and npm to the latest version available - [ ] I've completed the Bug section below - [ ] I've deleted this checklist section before I hit submit @@ -22,13 +21,14 @@ assignees: '' - **Browser:** Chrome / Safari / Lynx / ? + version - **Node version:** `node --version` - **NPM version:** `npm --version` -- **RethinkDB version:** `rethinkdb --version` ### Acceptance Criteria (optional) + Users can: - - Do this - - Do that - - Cannot do that -Triage is performed to find the root cause of the bug, timeboxed to ~1 hour. + +- Do this +- Do that +- Cannot do that + Triage is performed to find the root cause of the bug, timeboxed to ~1 hour. **Estimated effort:** 1 hour to triage. More if root cause is already identified. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6842fb2dc4..801cf583489 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,12 +31,6 @@ jobs: POSTGRES_DB: "tempdb" ports: - 5432:5432 - rethinkdb: - image: rethinkdb:2.4.2 - ports: - - 8080:8080 - - 28015:28015 - - 29015:29015 redis: image: redis:7.0-alpine ports: @@ -76,8 +70,7 @@ jobs: - name: Build the DBs run: | cp ${{ env.PARABOL_BUILD_ENV_PATH }} ./.env - yarn db:migrate - yarn pg:migrate up + yarn kysely migrate:latest yarn pg:build yarn pg:generate diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ba531a63838..79d6d4a079c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,12 +26,6 @@ jobs: POSTGRES_DB: "tempdb" ports: - 5432:5432 - rethinkdb: - image: rethinkdb:2.4.2 - ports: - - 8080:8080 - - 28015:28015 - - 29015:29015 redis: image: redis:7.0-alpine ports: @@ -76,8 +70,7 @@ jobs: - name: Build the DBs run: | cp ${{ env.PARABOL_BUILD_ENV_PATH }} ./.env - yarn db:migrate - yarn pg:migrate up + yarn kysely migrate:latest yarn pg:build - name: Build for testing diff --git a/.gitignore b/.gitignore index 805d98ce9ef..27e25baedc9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,6 @@ packages/server/graphql/public/resolverTypes.ts packages/server/types/gitlabTypes.ts packages/server/types/githubTypes.ts queryMap.json -rethinkdb_data/ -rethinkdb_dump_* schema.graphql scratch/ scripts/toolbox/* diff --git a/.husky/post-checkout b/.husky/post-checkout index 89870c954b5..fc811db0d5a 100755 --- a/.husky/post-checkout +++ b/.husky/post-checkout @@ -4,13 +4,12 @@ yarn postcheckout DELETED_POSTGRES_MIGRATIONS=$(git diff $1 $2 --name-only --diff-filter=D -- packages/server/postgres/migrations/) -DELETED_RETHINK_MIGRATIONS=$(git diff $1 $2 --name-only --diff-filter=D -- packages/server/database/migrations/) -if [ ! -z "$DELETED_POSTGRES_MIGRATIONS" -o ! -z "$DELETED_RETHINK_MIGRATIONS" ]; then +if [ ! -z "$DELETED_POSTGRES_MIGRATIONS" ]; then CURRENT_BRANCH=$(git branch --show-current) NUM_POSTGRES_MIGRATIONS=$(echo $DELETED_POSTGRES_MIGRATIONS | wc -w) echo "WARNING: You're leaving behind the following migrations not present on the current branch:" echo - for X in $DELETED_POSTGRES_MIGRATIONS $DELETED_RETHINK_MIGRATIONS; do + for X in $DELETED_POSTGRES_MIGRATIONS; do echo " ${X##*/}" done echo @@ -18,11 +17,8 @@ if [ ! -z "$DELETED_POSTGRES_MIGRATIONS" -o ! -z "$DELETED_RETHINK_MIGRATIONS" ] echo echo " git checkout ${1} &&" if [ ! -z "$DELETED_POSTGRES_MIGRATIONS" ]; then - echo " yarn pg:migrate down ${NUM_POSTGRES_MIGRATIONS} &&" + echo " yarn kysely migrate:down ${NUM_POSTGRES_MIGRATIONS} &&" fi - for X in $DELETED_RETHINK_MIGRATIONS; do - echo " yarn db:migrate down &&" - done echo " git checkout ${CURRENT_BRANCH:-$2}" echo fi diff --git a/README.md b/README.md index fe55f4673d0..4fda806733c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ our company's [history and SaaS metrics](https://www.parabol.co/blog/tag/friday- | ---------------------- | --------------------------------------------------------------- | | Server | [Node](https://nodejs.org/) | | Server Framework | [μWebSockets.js](https://github.com/uNetworking/uWebSockets.js) | -| Database (Legacy) | [RethinkDB](https://www.rethinkdb.com/) | | Database | [PostgreSQL](https://www.postgresql.org/) | | PubSub & Cache | [Redis](https://redis.io) | | Data Transport | [GraphQL](https://github.com/graphql/graphql-js) | @@ -65,7 +64,6 @@ $ yarn dev - [GraphQL Executor](./packages/gql-executor/README.md) - [Integrations (GitHub, Jira, Slack, etc.)](./docs/integrations.md) - [PostgreSQL](./packages/server/postgres/README.md) -- [RethinkDB](./packages/server/database/README.md) - [Shared Scripts](./packages/client/shared/README.md) - [VS Code Tips](.vscode/tips.md) - [Tailwind CSS migration guide](./packages/client/README.md) diff --git a/docker/images/parabol-ubi/README.md b/docker/images/parabol-ubi/README.md index f6f8692cc38..79d0ee4bc58 100644 --- a/docker/images/parabol-ubi/README.md +++ b/docker/images/parabol-ubi/README.md @@ -10,7 +10,7 @@ To build it locally (unsupported), use [act](https://github.com/nektos/act) to r ## Run the application using a docker image -_Assumes redis, rethinkdb, and postgres already running to have operational stack._ +_Assumes redis and postgres already running to have operational stack._ The commands below will start a Parabol container on the target tag specified in \_DOCKER_TAG export. It will volume mount a .env in your current working directory to the container, so you can pass in any .env in your current working directory. diff --git a/docker/images/parabol-ubi/environments/basic-env b/docker/images/parabol-ubi/environments/basic-env index 7141dd3f371..8acf98985aa 100644 --- a/docker/images/parabol-ubi/environments/basic-env +++ b/docker/images/parabol-ubi/environments/basic-env @@ -11,7 +11,5 @@ POSTGRES_DB='tempdb' POSTGRES_HOST='localhost' POSTGRES_PORT='5432' REDIS_URL='redis://localhost:6379' -RETHINKDB_SSL='' -RETHINKDB_URL='rethinkdb://localhost:28015/buildDB' SERVER_ID='0' SERVER_SECRET='FAKE_VALUE' diff --git a/docker/images/parabol-ubi/environments/pipeline b/docker/images/parabol-ubi/environments/pipeline index a6e21190ff2..9cb35c6cea5 100644 --- a/docker/images/parabol-ubi/environments/pipeline +++ b/docker/images/parabol-ubi/environments/pipeline @@ -42,8 +42,6 @@ POSTGRES_DB='tempdb' POSTGRES_HOST='localhost' POSTGRES_PORT='5432' REDIS_URL='redis://localhost:6379' -RETHINKDB_SSL='' -RETHINKDB_URL='rethinkdb://localhost:28015/actionProduction' SENTRY_DSN='' SERVER_ID='0' SERVER_SECRET='FAKE_VALUE' diff --git a/docker/stacks/development/README.md b/docker/stacks/development/README.md index a14d00d59cb..9d05ff6303b 100644 --- a/docker/stacks/development/README.md +++ b/docker/stacks/development/README.md @@ -10,7 +10,6 @@ ## Components - **Datadog agent:** additional configuration can be added in the folder `datadog/dd-conf.d`. -- **RethinkDB:** ports 28015 and 8080 (console) exposed to communicate with the cluster. Data mounted in a volume rethinkdb-data. - **Postgres:** container built from a Dockerfile in [docker/images/postgres](docker/images/postgres), that incorporates some extra extensions used by the application. Exposed through port 5432 and with the data mounted in a volume postgres-data. - **PGAdmin:** available on 5050 with credentials on the `.env` file. Connect using the values of `PGADMIN_DEFAULT_EMAIL` and `PGADMIN_DEFAULT_PASSWORD` from the `.env`. Data mounted on a volume pgadmin-data. - **Redis:** available on 6379 with the data mounted on a volume redis-data. diff --git a/docker/stacks/development/docker-compose.yml b/docker/stacks/development/docker-compose.yml index 82ac79c3551..3c0fb26c780 100644 --- a/docker/stacks/development/docker-compose.yml +++ b/docker/stacks/development/docker-compose.yml @@ -15,17 +15,6 @@ services: - /var/run/docker.sock:/var/run/docker.sock - /proc/:/host/proc/:ro - /sys/fs/cgroup:/host/sys/fs/cgroup:ro - rethinkdb: - image: rethinkdb:2.4.2 - restart: unless-stopped - ports: - - "8080:8080" - - "29015:29015" - - "28015:28015" - volumes: - - rethink-data:/data - networks: - - parabol-network postgres: image: pgvector/pgvector:0.7.0-pg16 restart: unless-stopped @@ -84,7 +73,6 @@ networks: parabol-network: volumes: redis-data: {} - rethink-data: {} postgres-data: {} pgadmin-data: {} text-embeddings-inference-data: {} diff --git a/docker/stacks/single-tenant-host/docker-compose.yml b/docker/stacks/single-tenant-host/docker-compose.yml index 3c23afa7f8a..58e7096e0ef 100644 --- a/docker/stacks/single-tenant-host/docker-compose.yml +++ b/docker/stacks/single-tenant-host/docker-compose.yml @@ -1,17 +1,4 @@ services: - rethinkdb: - container_name: rethinkdb - profiles: ["databases"] - image: rethinkdb:2.4.2 - restart: always - ports: - - "8080:8080" - - "29015:29015" - - "28015:28015" - volumes: - - ./data/rethink:/data - networks: - - parabol-network postgres: container_name: postgres profiles: ["databases"] @@ -98,8 +85,6 @@ services: volumes: - "./.env:/parabol/.env" depends_on: - rethinkdb: - condition: service_started postgres: condition: service_healthy redis: @@ -120,8 +105,6 @@ services: depends_on: pre-deploy: condition: service_completed_successfully - rethinkdb: - condition: service_started postgres: condition: service_healthy redis: @@ -144,8 +127,6 @@ services: depends_on: pre-deploy: condition: service_completed_successfully - rethinkdb: - condition: service_started postgres: condition: service_healthy redis: @@ -166,8 +147,6 @@ services: depends_on: pre-deploy: condition: service_completed_successfully - rethinkdb: - condition: service_started postgres: condition: service_healthy redis: @@ -188,8 +167,6 @@ services: depends_on: pre-deploy: condition: service_completed_successfully - rethinkdb: - condition: service_started postgres: condition: service_healthy redis: diff --git a/docs/alternative-licenses/us-department-of-defense/README.md b/docs/alternative-licenses/us-department-of-defense/README.md index 330f56931d5..8d22d6a4250 100644 --- a/docs/alternative-licenses/us-department-of-defense/README.md +++ b/docs/alternative-licenses/us-department-of-defense/README.md @@ -30,7 +30,6 @@ For all matters, please contact: support@parabol.co | ---------------------- | -------------------------------------------------------------- | | Server | [Node](https://nodejs.org/) | | Server Framework | [uWebSockts.js](https://github.com/uNetworking/uWebSockets.js) | -| Database (Legacy) | [RethinkDB](https://www.rethinkdb.com/) | | Database | [PostgreSQL](https://www.postgresql.org/) | | PubSub & Cache | [Redis](https://redis.io) | | Data Transport | [GraphQL](https://github.com/graphql/graphql-js) | @@ -70,11 +69,6 @@ Build for production and start application: $ yarn && yarn build && yarn start ``` -### RethinkDB - -- Migrations are stored in `packages/server/database/migrations` -- RethinkDB Dashboard is at [http://localhost:8080](http://localhost:8080) - ### PostgreSQL - pgadmin is at [http://localhost:5050](http://localhost:5050) diff --git a/package.json b/package.json index 75c4b69ce7a..528f0260c6c 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,10 @@ "clean": "git clean -fdx -e .env", "codegen": "node scripts/codegenGraphQL.js", "pg:build": "pgtyped -c ./packages/server/postgres/pgtypedConfig.js", - "pg:migrate": "node-pg-migrate -f ./packages/server/postgres/pgmConfig.js", "pg:generate": "export $(grep ^POSTGRES_ .env | tr -d \"'\"); yarn kysely-codegen --exclude-pattern \"(PgMigrations|StripeQuantityMismatchLogging)\" --out-file ./packages/server/postgres/pg.d.ts --dialect postgres --url postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$POSTGRES_PORT/$POSTGRES_DB && prettier --write ./packages/server/postgres/pg.d.ts", "pg:restore": "node ./scripts/toolbox/pgRestore.js", "db:start": "docker compose -f docker/stacks/development/docker-compose.yml up -d", "db:stop": "docker compose -f docker/stacks/development/docker-compose.yml down", - "db:migrate": "node scripts/migrate.js", "deduplicate": "yarn yarn-deduplicate yarn.lock", "predeploy": "node dist/preDeploy.js", "dev": "PM2_SILENT=true pm2 start pm2.dev.config.js --no-daemon", @@ -71,7 +69,6 @@ "git-url-parse": "12.0.0", "fbjs": "^3.0.0", "parse-url": "^8.1.0", - "rethinkdb-ts": "2.6.0", "recursive-readdir": "^2.2.3", "json5": "^2.2.3" }, @@ -94,6 +91,7 @@ "@types/dotenv": "^6.1.1", "@types/jscodeshift": "^0.11.3", "@types/lodash.toarray": "^4.4.7", + "@types/pg": "^8.11.10", "@typescript-eslint/eslint-plugin": "^8.3.0", "@typescript-eslint/parser": "^8.3.0", "autoprefixer": "^10.4.13", @@ -106,13 +104,13 @@ "html-webpack-plugin": "^5.5.0", "husky": "^7.0.4", "jscodeshift": "^0.14.0", - "kysely": "^0.27.3", + "kysely": "^0.27.4", "kysely-codegen": "^0.15.0", + "kysely-ctl": "^0.9.0", "lerna": "^6.4.1", "mini-css-extract-plugin": "^2.7.2", "minimist": "^1.2.5", "node-loader": "^2.0.0", - "pg-promise": "^11.2.0", "pm2": "^5.4.2", "postcss": "^8.4.21", "postcss-loader": "^7.0.2", @@ -139,6 +137,6 @@ "dotenv": "8.0.0", "dotenv-expand": "5.1.0", "lodash.toarray": "^4.4.0", - "rethinkdb-ts-migrate": "^0.3.6" + "pg": "^8.13.0" } } diff --git a/packages/embedder/indexing/retrospectiveDiscussionTopic.ts b/packages/embedder/indexing/retrospectiveDiscussionTopic.ts index b695d77c049..81f87bf7cff 100644 --- a/packages/embedder/indexing/retrospectiveDiscussionTopic.ts +++ b/packages/embedder/indexing/retrospectiveDiscussionTopic.ts @@ -73,7 +73,7 @@ export const createTextFromRetrospectiveDiscussionTopic = async ( dataLoader.get('retroReflectionsByGroupId').load(reflectionGroupId) ]) if (newMeeting.meetingType !== 'retrospective') throw new Error('Meeting is not a retro') - // It should never be undefined, but our data integrity in RethinkDB is bad + // It should never be undefined now that data is in PG. Can try removing & testing const templateId = newMeeting?.templateId ?? '' const promptIds = [...new Set(reflections.map((r) => r.promptId))] @@ -92,7 +92,7 @@ export const createTextFromRetrospectiveDiscussionTopic = async ( } for (const prompt of prompts) { - if (!prompt) continue // RethinkDB bad data integrity + if (!prompt) continue // Should never happen now that data is in PG if (!textForReranking) { markdown += `Participants were prompted with, "${prompt.question}` if (prompt.description) markdown += `: ${prompt.description}` diff --git a/packages/server/.prettierignore b/packages/server/.prettierignore index c5b5af599e1..c5680be6615 100644 --- a/packages/server/.prettierignore +++ b/packages/server/.prettierignore @@ -7,6 +7,5 @@ githubSchema.graphql gitlabSchema.graphql graphql/private/schema.graphql graphql/public/schema.graphql -migrationTemplate.ts billing/debug.ts pg.d.ts diff --git a/packages/server/__tests__/common.ts b/packages/server/__tests__/common.ts index 3a1e227d69a..4dadbc16fda 100644 --- a/packages/server/__tests__/common.ts +++ b/packages/server/__tests__/common.ts @@ -2,7 +2,6 @@ import base64url from 'base64url' import crypto from 'crypto' import faker from 'faker' import {sql} from 'kysely' -import getRethink from '../database/rethinkDriver' import ServerAuthToken from '../database/types/ServerAuthToken' import getKysely from '../postgres/getKysely' import encodeAuthToken from '../utils/encodeAuthToken' @@ -33,11 +32,6 @@ export async function sendIntranet(req: { return response.json() } -export const drainRethink = async () => { - const r = await getRethink() - r.getPoolMaster()?.drain() -} - const persistFunction = (text: string) => { const hasher = crypto.createHash('md5') hasher.update(text) diff --git a/packages/server/__tests__/globalTeardown.ts b/packages/server/__tests__/globalTeardown.ts index 03744b6ffa4..b85e0197f13 100644 --- a/packages/server/__tests__/globalTeardown.ts +++ b/packages/server/__tests__/globalTeardown.ts @@ -1,10 +1,7 @@ -import getRethink from '../database/rethinkDriver' import getKysely from '../postgres/getKysely' import getRedis from '../utils/getRedis' async function teardown() { - const r = await getRethink() - await r.getPoolMaster()?.drain() await getKysely().destroy() console.log('global teardown destroy') await getRedis().quit() diff --git a/packages/server/__tests__/setup.ts b/packages/server/__tests__/setup.ts index 4a4860682ff..c2fdf47b5bd 100644 --- a/packages/server/__tests__/setup.ts +++ b/packages/server/__tests__/setup.ts @@ -1,7 +1,2 @@ import * as matchers from 'jest-extended' -import {drainRethink} from './common' expect.extend(matchers) - -afterAll(() => { - return drainRethink() -}) diff --git a/packages/server/__tests__/startRetrospective.test.ts b/packages/server/__tests__/startRetrospective.test.ts index 2dc04eb1bd0..6bb436ac73d 100644 --- a/packages/server/__tests__/startRetrospective.test.ts +++ b/packages/server/__tests__/startRetrospective.test.ts @@ -1,8 +1,6 @@ -import getRethink from '../database/rethinkDriver' import {getUserTeams, sendPublic, signUp} from './common' test('Retro is named Retro #1 by default', async () => { - await getRethink() const {userId, authToken} = await signUp() const {id: teamId} = (await getUserTeams(userId))[0] @@ -42,7 +40,6 @@ test('Retro is named Retro #1 by default', async () => { }) test('Single Retro can be named', async () => { - await getRethink() const {userId, authToken} = await signUp() const {id: teamId} = (await getUserTeams(userId))[0] @@ -84,7 +81,6 @@ test('Single Retro can be named', async () => { }) test('Recurring retro is named like RetroSeries Jan 1', async () => { - await getRethink() const {userId, authToken} = await signUp() const {id: teamId} = (await getUserTeams(userId))[0] diff --git a/packages/server/database/README.md b/packages/server/database/README.md deleted file mode 100644 index 13d527b63d7..00000000000 --- a/packages/server/database/README.md +++ /dev/null @@ -1,12 +0,0 @@ -### RethinkDB - -RethinkDB is our legacy DB. -We are migrating all tables to [PostgresQL](../postgres/README.md) -We adopted it back in 2016 because it offered changefeeds, which made subscriptions easy. -Unfortunately, multi-table changefeeds did not scale well. -Thankfully, around 2017 GraphQL offered native subscriptions, which we adopted. -Around that same time, RethinkDB as a company went under, which meant updates ceased. -Since that time, RethinkDB has occassionally been unstable for us under high load. -Since our data is very relational, it made sense to move PostgresQL, which we are actively doing. - -- Migrations are stored in [`packages/server/database/migrations`](./migrations/) diff --git a/packages/server/database/cacert b/packages/server/database/cacert deleted file mode 100644 index 68787fac582..00000000000 --- a/packages/server/database/cacert +++ /dev/null @@ -1 +0,0 @@ -put your ssl cert here! diff --git a/packages/server/database/connectRethinkDB.ts b/packages/server/database/connectRethinkDB.ts deleted file mode 100644 index 0a25d6e8d10..00000000000 --- a/packages/server/database/connectRethinkDB.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {r} from 'rethinkdb-ts' -import {ParabolR} from './rethinkDriver' - -const connectRethinkDB = async () => { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) - return r as any as ParabolR -} - -export default connectRethinkDB diff --git a/packages/server/database/getRethinkConfig.ts b/packages/server/database/getRethinkConfig.ts deleted file mode 100644 index f7ef3e29347..00000000000 --- a/packages/server/database/getRethinkConfig.ts +++ /dev/null @@ -1,34 +0,0 @@ -import dotenv from 'dotenv' -import flag from 'node-env-flag' -import path from 'path' -import {parse} from 'url' -import readCert from './readCert' - -export default function getRethinkConfig() { - const envFile = path.join(__dirname, '../../../', '.env') - dotenv.config({path: envFile}) - const urlString = process.env.RETHINKDB_URL - if (!urlString) throw new Error('Invalid RETHINKDB_URL in ENV') - const u = parse(urlString) - if (!u.port || !u.path) throw new Error('Invalid RethinkDB URL') - const config = { - host: u.hostname || '', - port: parseInt(u.port, 10), - authKey: process.env.RETHINKDB_AUTH_KEY || '', - db: u.path.split('/')[1], - min: process.env.NODE_ENV === 'production' ? 50 : 3, - buffer: process.env.NODE_ENV === 'production' ? 50 : 3 - } - - if (process.env.NODE_ENV && flag(process.env.RETHINKDB_SSL)) { - // we may need a cert for production deployment - // Compose.io requires this, for example. - // https://www.compose.io/articles/rethinkdb-and-ssl-think-secure/ - Object.assign(config, { - ssl: { - ca: readCert() - } - }) - } - return config -} diff --git a/packages/server/database/migrations/20160715095300-initialize.js b/packages/server/database/migrations/20160715095300-initialize.js deleted file mode 100644 index f356ee39e5c..00000000000 --- a/packages/server/database/migrations/20160715095300-initialize.js +++ /dev/null @@ -1,39 +0,0 @@ -exports.up = async (r) => { - const initialTables = [ - r.tableCreate('User').run(), - r.tableCreate('TeamMember').run(), - r.tableCreate('Invitation').run(), - r.tableCreate('Team').run() - ] - await Promise.all(initialTables) - const initialIndices = [ - r - .table('TeamMember') - .indexCreate('teamId') - .run(), - r - .table('TeamMember') - .indexCreate('userId') - .run(), - // one row per invite, even resending an invite gets a new row - r - .table('Invitation') - .indexCreate('teamId') - .run(), - r - .table('Invitation') - .indexCreate('email') - .run() - ] - await Promise.all(initialIndices) -} - -exports.down = async (r) => { - const initialTables = [ - r.tableDrop('User').run(), - r.tableDrop('TeamMember').run(), - r.tableDrop('Invitation').run(), - r.tableDrop('Team').run() - ] - await Promise.all(initialTables) -} diff --git a/packages/server/database/migrations/20160722161700-meeting.js b/packages/server/database/migrations/20160722161700-meeting.js deleted file mode 100644 index 52196ada089..00000000000 --- a/packages/server/database/migrations/20160722161700-meeting.js +++ /dev/null @@ -1,56 +0,0 @@ -exports.up = async (r) => { - const meetingTables = [ - r.tableCreate('Action').run(), - r.tableCreate('AgendaItem').run(), - r.tableCreate('Meeting').run(), - r.tableCreate('Participant').run(), - r.tableCreate('Project').run(), - r.tableCreate('Outcome').run(), - r.tableCreate('TaskOutcomeDiff').run() - ] - await Promise.all(meetingTables) - const meetingIndices = [ - r - .table('Action') - .indexCreate('userId') - .run(), - r - .table('AgendaItem') - .indexCreate('teamId') - .run(), - r - .table('Meeting') - .indexCreate('teamId') - .run(), - r - .table('Participant') - .indexCreate('meetingId') - .run(), - r - .table('Participant') - .indexCreate('userId') - .run(), - r - .table('Project') - .indexCreate('teamMemberId') - .run(), - r - .table('Project') - .indexCreate('teamIdCreatedAt', (row) => [row('teamId'), row('createdAt')]) - .run() - ] - await Promise.all(meetingIndices) -} - -exports.down = async (r) => { - const meetingTables = [ - r.tableDrop('Action').run(), - r.tableDrop('AgendaItem').run(), - r.tableDrop('Meeting').run(), - r.tableDrop('Participant').run(), - r.tableDrop('Project').run(), - r.tableDrop('Outcome').run(), - r.tableDrop('TaskOutcomeDiff').run() - ] - await Promise.all(meetingTables) -} diff --git a/packages/server/database/migrations/20160726160100-mockTeam.js b/packages/server/database/migrations/20160726160100-mockTeam.js deleted file mode 100644 index 13e5fb40bc8..00000000000 --- a/packages/server/database/migrations/20160726160100-mockTeam.js +++ /dev/null @@ -1,177 +0,0 @@ -import { LOBBY } from 'parabol-client/utils/constants' - -/* eslint-disable max-len */ -exports.up = async (r) => { - const users = [ - { - id: 'auth0|5ad184ad6d59890e8635d9e4', - email: 'taya@prbl.co', - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/2016+Taya+Mueller.jpg?t=1523658193243', - preferredName: 'Taya' - }, - { - id: 'auth0|5ad119debcb4500e4f4e2808', - email: 'jordan@prbl.co', - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/2016+Jordan+Husney.jpg?t=1523658193243', - preferredName: 'Jordan' - }, - { - id: 'auth0|5ad184fabcb4500e4f4e345e', - email: 'terry@prbl.co', - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/terry.jpg?t=1523658193243', - preferredName: 'Terry' - }, - { - id: 'auth0|5ad1851a6d59890e8635d9eb', - email: 'matt@prbl.co', - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/matt.jpg?t=1523658193243', - preferredName: 'Matt' - } - ] - const team = { - id: 'team123', - name: 'Parabol', - facilitatorPhase: LOBBY, - meetingPhase: LOBBY, - meetingId: null, - facilitatorPhaseItem: null, - meetingPhaseItem: null, - activeFacilitator: null - } - const teamMembers = [ - { - id: 'auth0|5ad119debcb4500e4f4e2808::team123', - isActive: true, - isFacilitator: true, - isLead: true, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/2016+Jordan+Husney.jpg?t=1523658193243', - preferredName: 'Jordan', - teamId: 'team123', - userId: 'auth0|5ad119debcb4500e4f4e2808' - }, - { - id: 'auth0|5ad184fabcb4500e4f4e345e::team123', - isActive: true, - isFacilitator: true, - isLead: false, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/terry.jpg?t=1523658193243', - preferredName: 'Terry', - teamId: 'team123', - userId: 'auth0|5ad184fabcb4500e4f4e345e' - }, - { - id: 'auth0|5ad184ad6d59890e8635d9e4::team123', - isActive: true, - isFacilitator: true, - isLead: false, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/2016+Taya+Mueller.jpg?t=1523658193243', - preferredName: 'Taya', - teamId: 'team123', - userId: 'auth0|5ad184ad6d59890e8635d9e4' - }, - { - id: 'auth0|5ad1851a6d59890e8635d9eb::team123', - isActive: true, - isFacilitator: true, - isLead: false, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/matt.jpg?t=1523658193243', - preferredName: 'Matt', - teamId: 'team123', - userId: 'auth0|5ad1851a6d59890e8635d9eb' - } - ] - const engineeringTeam = { - id: 'team456', - name: 'Engineering', - facilitatorPhase: LOBBY, - meetingPhase: LOBBY, - meetingId: null, - facilitatorPhaseItem: null, - meetingPhaseItem: null, - activeFacilitator: null - } - const engineeringMembers = [ - { - id: 'auth0|5ad119debcb4500e4f4e2808::team456', - isActive: true, - isFacilitator: true, - isLead: false, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/2016+Jordan+Husney.jpg?t=1523658193243', - preferredName: 'Jordan', - teamId: 'team456', - userId: 'auth0|5ad119debcb4500e4f4e2808' - }, - { - id: 'auth0|5ad184fabcb4500e4f4e345e::team456', - isActive: false, - isFacilitator: true, - isLead: false, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/terry.jpg?t=1523658193243', - preferredName: 'Terry', - teamId: 'team456', - userId: 'auth0|5ad184fabcb4500e4f4e345e' - }, - { - id: 'auth0|5ad1851a6d59890e8635d9eb::team456', - isActive: true, - isFacilitator: true, - isLead: true, - picture: - 'https://www.parabol.co/hubfs/website/2018-01/assets/dist/images/team/matt.jpg?t=1523658193243', - preferredName: 'Matt', - teamId: 'team456', - userId: 'auth0|5ad1851a6d59890e8635d9eb' - } - ] - const mockUsers = [ - r - .table('User') - .insert(users) - .run(), - r - .table('Team') - .insert(team) - .run(), - r - .table('Team') - .insert(engineeringTeam) - .run(), - r - .table('TeamMember') - .insert(teamMembers) - .run(), - r - .table('TeamMember') - .insert(engineeringMembers) - .run() - ] - await Promise.all(mockUsers) -} - -exports.down = async (r) => { - const meetingTables = [ - r - .table('User') - .delete() - .run(), - r - .table('TeamMember') - .delete() - .run(), - r - .table('Team') - .delete() - .run() - ] - await Promise.all(meetingTables) -} diff --git a/packages/server/database/migrations/20160906105600-add-agenda-ids.js b/packages/server/database/migrations/20160906105600-add-agenda-ids.js deleted file mode 100644 index ed1d52d1720..00000000000 --- a/packages/server/database/migrations/20160906105600-add-agenda-ids.js +++ /dev/null @@ -1,50 +0,0 @@ -const AGENDA_ID_FIELD = 'agendaId' - -/* eslint-disable max-len */ -exports.up = async (r) => { - const withAgendaId = { - [AGENDA_ID_FIELD]: null - } - const queries = [ - r - .table('Action') - .update(withAgendaId) - .run(), - r - .table('Action') - .indexCreate('teamMemberId') - .run(), - r - .table('Action') - .indexCreate('agendaId') - .run(), - r - .table('Project') - .update(withAgendaId) - .run() - ] - await Promise.all(queries) -} - -exports.down = async (r) => { - const withoutAgendaId = r.row.without(AGENDA_ID_FIELD) - const queries = [ - r - .table('Action') - .replace(withoutAgendaId) - .run(), - r - .table('Action') - .indexDrop('teamMemberId') - .run(), - r - .table('Action') - .indexDrop('agendaId') - .run(), - r - .table('Project') - .replace(withoutAgendaId) - .run() - ] - await Promise.all(queries) -} diff --git a/packages/server/database/migrations/20160923154400-project-archive.js b/packages/server/database/migrations/20160923154400-project-archive.js deleted file mode 100644 index b50a043c3f7..00000000000 --- a/packages/server/database/migrations/20160923154400-project-archive.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable max-len */ -exports.up = async (r) => { - const queries = [ - r - .table('Project') - .update((doc) => ({ - isArchived: false, - teamId: doc('id') - .split('::') - .nth(0) - })) - .run(), - r - .table('Project') - .indexCreate('teamId') - .run() - ] - await Promise.all(queries) -} - -exports.down = async (r) => { - const queries = [ - r - .table('Project') - .indexDrop('teamId') - .run(), - r - .table('Project') - .replace(r.row.without('teamId', 'isArchived')) - .run() - ] - await Promise.all(queries) -} diff --git a/packages/server/database/migrations/20161013161900-project-history.js b/packages/server/database/migrations/20161013161900-project-history.js deleted file mode 100644 index 00804c08af0..00000000000 --- a/packages/server/database/migrations/20161013161900-project-history.js +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint-disable max-len */ -exports.up = async (r) => { - const tables = [r.tableCreate('ProjectHistory').run(), r.tableDrop('TaskOutcomeDiff').run()] - await Promise.all(tables) - const indices = [ - r - .table('ProjectHistory') - .indexCreate('projectIdUpdatedAt', (row) => [row('projectId'), row('updatedAt')]) - .run(), - r - .table('Project') - .indexCreate('agendaId') - .run() - ] - await Promise.all(indices) -} - -exports.down = async (r) => { - const tables = [r.tableDrop('ProjectHistory').run(), r.tableCreate('TaskOutcomeDiff').run()] - await Promise.all(tables) - const indices = [ - r - .table('Project') - .indexDrop('agendaId') - .run() - ] - await Promise.all(indices) -} diff --git a/packages/server/database/migrations/20161105214300-invitation.js b/packages/server/database/migrations/20161105214300-invitation.js deleted file mode 100644 index 4553a2e29f5..00000000000 --- a/packages/server/database/migrations/20161105214300-invitation.js +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable max-len */ -exports.up = async (r) => { - const indices = [ - r - .table('Project') - .indexCreate('tokenExpiration') - .run() - ] - await Promise.all(indices) - const fields = [ - r - .table('TeamMember') - .update( - { - email: r - .table('User') - .get((row) => { - return row('userId') - })('email') - .default('') - }, - {nonAtomic: true} - ) - .run() - ] - await Promise.all(fields) -} - -exports.down = async (r) => { - const indices = [ - r - .table('Project') - .indexDrop('tokenExpiration') - .run() - ] - await Promise.all(indices) - const fields = [ - r - .table('TeamMember') - .replace(r.row.without('email')) - .run() - ] - await Promise.all(fields) -} diff --git a/packages/server/database/migrations/20161114214000-allFacilitators.js b/packages/server/database/migrations/20161114214000-allFacilitators.js deleted file mode 100644 index 644b691a8f0..00000000000 --- a/packages/server/database/migrations/20161114214000-allFacilitators.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable max-len */ -exports.up = async (r) => { - const fields = [ - r - .table('TeamMember') - .replace((row) => { - return row.without('isActive').merge({ - isFacilitator: true, - isNotRemoved: row('isActive') - }) - }) - .run() - ] - await Promise.all(fields) -} - -exports.down = async (r) => { - const fields = [ - r - .table('TeamMember') - .replace((row) => { - return row.without('isNotRemoved').merge({ - isActive: row('isNotRemoved') - }) - }) - .run() - ] - await Promise.all(fields) -} diff --git a/packages/server/database/migrations/20161121091100-addTmsOnMock.js b/packages/server/database/migrations/20161121091100-addTmsOnMock.js deleted file mode 100644 index 0c31444bdf2..00000000000 --- a/packages/server/database/migrations/20161121091100-addTmsOnMock.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable max-len */ -// taya, jordan, terry, matt -const productTeam = [ - 'auth0|5ad119debcb4500e4f4e2808', - 'auth0|5ad184fabcb4500e4f4e345e', - 'auth0|5ad184ad6d59890e8635d9e4', - 'auth0|5ad1851a6d59890e8635d9eb' -] -const engineeringTeam = [ - 'auth0|5ad119debcb4500e4f4e2808', - 'auth0|5ad184fabcb4500e4f4e345e', - 'auth0|5ad1851a6d59890e8635d9eb' -] -exports.up = async (r) => { - const fields = [ - r - .table('User') - .getAll(r.args(engineeringTeam), {index: 'id'}) - .update({tms: ['team123', 'team456']}) - .run(), - r - .table('User') - .get(productTeam[0]) - .update({tms: ['team123']}) - .run() - ] - await Promise.all(fields) -} - -exports.down = async (r) => { - const fields = [ - r - .table('User') - .getAll(r.args(productTeam)) - .update({tms: []}) - .run() - ] - await Promise.all(fields) -} diff --git a/packages/server/database/migrations/20161125141100-addOrgs.js b/packages/server/database/migrations/20161125141100-addOrgs.js deleted file mode 100644 index 7091c09cc32..00000000000 --- a/packages/server/database/migrations/20161125141100-addOrgs.js +++ /dev/null @@ -1,314 +0,0 @@ -import ms from 'ms' -import {TRIAL_EXPIRES_SOON} from 'parabol-client/utils/constants' -import {fromEpochSeconds} from '../../utils/epochTime' - -const TRIAL_PERIOD_DAYS = 30 -const TRIAL_EXPIRES_SOON_DELAY = ms('14d') -/* eslint-disable max-len */ - -exports.up = async (r) => { - let counter = 0 - const tables = [r.tableCreate('Organization').run(), r.tableCreate('Notification').run()] - try { - await Promise.all(tables) - } catch (e) { - // ignore - } - const indices = [ - // need index on periodEnd still? - // r.table('Organization').indexCreate('periodEnd'), - r - .table('Organization') - .indexCreate('orgUsers', r.row('orgUsers')('id'), {multi: true}) - .run(), - r - .table('ProjectHistory') - .indexCreate('teamMemberId') - .run(), - r - .table('Team') - .indexCreate('orgId') - .run(), - r - .table('Notification') - .indexCreate('orgId') - .run(), - r - .table('Notification') - .indexCreate('userIds', {multi: true}) - .run(), - // r.table('User').indexCreate('email'), - r - .table('User') - .indexCreate('userOrgs', r.row('userOrgs')('id'), {multi: true}) - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } - - const waitIndices = [ - r - .table('Team') - .indexWait('orgId') - .run(), - r - .table('Notification') - .indexWait('orgId', 'userIds') - .run(), - r - .table('User') - .indexWait('userOrgs') - .run() - ] - await Promise.all(waitIndices) - - if (process.env.NODE_ENV !== 'production') { - console.warn('NODE_ENV is testing. Removing, not migrating prior users.') - const purgeTasks = [ - r - .table('Team') - .delete() - .run(), - r - .table('TeamMember') - .delete() - .run(), - r - .table('User') - .delete() - .run() - ] - await Promise.all(purgeTasks) - return - } - - const now = new Date() - // every team leader is going to be promoted to an org leader - // this means if i was invited to a team then created my own team, where i'm the leader, that will be a new org - const teamMembers = await r.table('TeamMember').run() - const teamLeaders = teamMembers.filter((member) => member.isLead === true) - const orgLookupByUserId = {} - const orgLookupByTeam = {} - for (let i = 0; i < teamLeaders.length; i++) { - const teamLeader = teamLeaders[i] - const {teamId, userId} = teamLeader - orgLookupByUserId[userId] = orgLookupByUserId[userId] || String(counter++) - orgLookupByTeam[teamId] = orgLookupByUserId[userId] - } - - const orgs = {} - const users = {} - for (let i = 0; i < teamMembers.length; i++) { - const teamMember = teamMembers[i] - const {isLead, preferredName, userId, teamId} = teamMember - const orgId = orgLookupByTeam[teamId] - teamMember.orgId = orgId - orgs[orgId] = orgs[orgId] || {} - orgs[orgId].orgUserMap = orgs[orgId].orgUserMap || {} - orgs[orgId].orgUserMap[userId] = isLead - users[userId] = users[userId] || {} - users[userId].userOrgMap = users[userId].userOrgMap || {} - users[userId].userOrgMap[orgId] = isLead - if (isLead) { - orgs[orgId].leaderId = userId - orgs[orgId].name = `${preferredName}’s Org` - users[userId].trialOrg = orgId - } - } - // turned into a noop to remove dependency on stripe - const subscriptions = [] - // const orgIds = Object.keys(orgs) - // const stripeCustomers = await Promise.all( - // orgIds.map((orgId) => stripe.customers.create({metadata: {orgId}})) - // ) - // const subscriptions = await Promise.all( - // stripeCustomers.map((customer) => { - // return stripe.subscriptions.create({ - // customer: customer.id, - // metadata: customer.metadata, - // plan: 'parabol-pro-monthly', - // quantity: Object.keys(orgs[customer.metadata.orgId].orgUserMap).length, - // trial_period_days: TRIAL_PERIOD_DAYS - // }) - // }) - // ) - const orgsForDB = [] - const notificationsForDB = [] - for (let i = 0; i < subscriptions.length; i++) { - const subscription = subscriptions[i] - const currentPeriodStart = subscription.current_period_start - const currentPeriodEnd = subscription.current_period_end - const { - metadata: {orgId}, - customer, - id - } = subscription - const periodEnd = fromEpochSeconds(currentPeriodEnd) - const {leaderId, name, orgUserMap} = orgs[orgId] - const orgUserIds = Object.keys(orgUserMap) - const orgUsers = [] - for (let j = 0; j < orgUserIds.length; j++) { - const orgUserId = orgUserIds[j] - orgUsers[j] = { - id: orgUserId, - role: orgUserMap[orgUserId] ? 'billingLeader' : null, - inactive: false - } - } - orgsForDB[i] = { - id: orgId, - createdAt: now, - creditCard: {}, - name, - orgUsers, - stripeId: customer, - stripeSubscriptionId: id, - updatedAt: now, - periodEnd, - periodStart: fromEpochSeconds(currentPeriodStart) - } - notificationsForDB[i] = { - id: String(counter++), - type: TRIAL_EXPIRES_SOON, - startAt: new Date(now.getTime() + TRIAL_EXPIRES_SOON_DELAY), - userIds: [leaderId], - orgId, - varList: [periodEnd] - } - } - - const usersForDB = [] - const userIds = Object.keys(users) - for (let i = 0; i < userIds.length; i++) { - const userId = userIds[i] - const user = users[userId] - const {trialOrg, userOrgMap} = user - const userOrgs = [] - const userOrgIds = Object.keys(userOrgMap) - for (let j = 0; j < userOrgIds.length; j++) { - const userOrgId = userOrgIds[j] - userOrgs[j] = { - id: userOrgId, - role: userOrgMap[userOrgId] ? 'billingLeader' : null - } - } - usersForDB[i] = { - id: userId, - trialOrg, - userOrgs - } - } - - // create updates to make to team docs - const teamIds = Object.keys(orgLookupByTeam) - const teamsForDB = [] - for (let i = 0; i < teamIds.length; i++) { - const teamId = teamIds[i] - teamsForDB[i] = { - id: teamId, - orgId: orgLookupByTeam[teamId] - } - } - - const teamUpdates = r - .expr(teamsForDB) - .forEach((team) => - r - .table('Team') - .get(team('id')) - .update({ - orgId: team('orgId'), - isPaid: true - }) - ) - .run() - - const userUpdates = r - .expr(usersForDB) - .forEach((user) => - r - .table('User') - .get(user('id')) - .update( - { - inactive: false, - trialOrg: user('trialOrg').default(null), - userOrgs: user('userOrgs') - }, - {returnChanges: true} - ) - ) - .run() - - const orgInserts = r - .table('Organization') - .insert(orgsForDB) - .run() - const notificationInserts = r - .table('Notification') - .insert(notificationsForDB) - .run() - - try { - await Promise.all([teamUpdates, userUpdates, orgInserts, notificationInserts]) - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - // removes ALL customers from stripe. DOING THIS SUCKS FOR DEV SINCE WE ALL HAVE DIFFERENT DBS - // const stripeCustomers = []; - // for (let i = 0; i < 100; i++) { - // const options = {limit: 100}; - // if (i > 0) { - // options.starting_after = stripeCustomers[stripeCustomers.length - 1].id; - // } - // const customers = await stripe.customers.list(options); - // stripeCustomers.push(...customers.data); - // if (!customers.has_more) break; - // } - - try { - const stripeIds = await r - .table('Organization')('stripeId') - .run() - // await Promise.all(stripeIds.map((id) => stripe.customers.del(id))) - } catch (e) { - console.log(`not all customers existed: ${e}`) - } - - const tables = [ - r.tableDrop('Organization').run(), - r - .table('ProjectHistory') - .indexDrop('teamMemberId') - .run(), - r.tableDrop('Notification').run(), - r - .table('Team') - .indexDrop('orgId') - .run(), - // r.table('User').indexDrop('email').run(), - r - .table('User') - .indexDrop('userOrgs') - .run(), - r - .table('Team') - .replace((row) => row.without('orgId')) - .run(), - r - .table('User') - .replace((row) => row.without('trialOrg', 'userOrgs')) - .run() - ] - try { - await Promise.all(tables) - } catch (e) { - // ignore - } -} diff --git a/packages/server/database/migrations/20170112135700-addInvoice.js b/packages/server/database/migrations/20170112135700-addInvoice.js deleted file mode 100644 index d57aa12390a..00000000000 --- a/packages/server/database/migrations/20170112135700-addInvoice.js +++ /dev/null @@ -1,33 +0,0 @@ -exports.up = async (r) => { - const tables = [r.tableCreate('Invoice').run(), r.tableCreate('InvoiceItemHook').run()] - try { - await Promise.all(tables) - } catch (e) { - // ignore - } - const indices = [ - r - .table('Invoice') - .indexCreate('orgIdStartAt', (row) => [row('orgId'), row('startAt')]) - .run(), - r - .table('InvoiceItemHook') - .indexCreate('prorationDate') - .run(), - r - .table('InvoiceItemHook') - .indexCreate('userId') - .run() - // r.table('InvoiceItemHook').indexCreate('prorationDateSubId', (row) => [row('prorationDate'), row('subId')]) - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } -} - -exports.down = async (r) => { - const tables = [r.tableDrop('Invoice').run(), r.tableDrop('InvoiceItemHook').run()] - await Promise.all(tables) -} diff --git a/packages/server/database/migrations/20170202190500-addOrgApprovals.js b/packages/server/database/migrations/20170202190500-addOrgApprovals.js deleted file mode 100644 index 48f3723f02d..00000000000 --- a/packages/server/database/migrations/20170202190500-addOrgApprovals.js +++ /dev/null @@ -1,47 +0,0 @@ -exports.up = async (r) => { - const tables = [ - r.tableCreate('OrgApproval').run(), - r.tableDrop('Participant').run() // unused table - ] - try { - await Promise.all(tables) - } catch (e) { - // ignore - } - const indices = [ - r - .table('OrgApproval') - .indexCreate('teamId') - .run(), - r - .table('OrgApproval') - .indexCreate('email') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } -} - -exports.down = async (r) => { - const tables = [ - r.tableDrop('OrgApproval'), - r.tableCreate('Participant') // unused table - ] - try { - await Promise.all(tables) - } catch (e) { - // ignore - } - const indices = [ - r.table('Participant').indexCreate('meetingId'), // unused table - r.table('Participant').indexCreate('userId') // unused table - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } -} diff --git a/packages/server/database/migrations/20170228132400-cleanupProjectIndices.js b/packages/server/database/migrations/20170228132400-cleanupProjectIndices.js deleted file mode 100644 index 750afddc2b3..00000000000 --- a/packages/server/database/migrations/20170228132400-cleanupProjectIndices.js +++ /dev/null @@ -1,67 +0,0 @@ -exports.up = async (r) => { - const fields = [ - r - .table('Project') - .replace( - (row) => { - return row - .merge({ - sortOrder: row('teamSort').default(r.random()) - }) - .without('teamSort', 'userSort') - }, - {nonAtomic: true} - ) - .run() - ] - await Promise.all(fields) - - const indices = [ - r - .table('Project') - .indexDrop('tokenExpiration') - .run(), - r - .table('Project') - .indexCreate('userId') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } -} - -exports.down = async (r) => { - const fields = [ - r - .table('Project') - .replace((row) => { - return row - .merge({ - teamSort: row('sortOrder'), - userSort: row('sortOrder') - }) - .without('sortOrder') - }) - .run() - ] - await Promise.all(fields) - - const indices = [ - r - .table('Project') - .indexCreate('tokenExpiration') - .run(), - r - .table('Project') - .indexDrop('userId') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } -} diff --git a/packages/server/database/migrations/20170316073600-segmentIdentify.js b/packages/server/database/migrations/20170316073600-segmentIdentify.js deleted file mode 100644 index 5e265d380bd..00000000000 --- a/packages/server/database/migrations/20170316073600-segmentIdentify.js +++ /dev/null @@ -1,3 +0,0 @@ -exports.up = async () => {} - -exports.down = async () => {} diff --git a/packages/server/database/migrations/20170330174100-addTeamIsArchived.js b/packages/server/database/migrations/20170330174100-addTeamIsArchived.js deleted file mode 100644 index ba9cdb46256..00000000000 --- a/packages/server/database/migrations/20170330174100-addTeamIsArchived.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.up = async (r) => { - await r - .table('Team') - .update({isArchived: false}) - .run() -} - -exports.down = async (r) => { - await r - .table('Action') - .replace(r.row.without('isArchived')) - .run() -} diff --git a/packages/server/database/migrations/20170418145600-checkInGreetingObject.js b/packages/server/database/migrations/20170418145600-checkInGreetingObject.js deleted file mode 100644 index 1cb8681680e..00000000000 --- a/packages/server/database/migrations/20170418145600-checkInGreetingObject.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.up = async (r) => { - await r - .table('Team') - .replace(r.row.without('checkInGreeting')) - .run() -} - -exports.down = async (r) => { - await r - .table('Team') - .replace(r.row.without('checkInGreeting')) - .run() -} diff --git a/packages/server/database/migrations/20170502190200-addTags.js b/packages/server/database/migrations/20170502190200-addTags.js deleted file mode 100644 index ed64e939dba..00000000000 --- a/packages/server/database/migrations/20170502190200-addTags.js +++ /dev/null @@ -1,145 +0,0 @@ -exports.up = async (r) => { - const mutations = [ - r.table('Action').run(), - r - .table('Project') - .replace((project) => { - return r.branch( - project('isArchived') - .eq(true) - .default(false), - project - .merge({ - tags: ['#archived'] - }) - .without('isArchived'), - project - .merge({ - tags: [] - }) - .without('isArchived') - ) - }) - .run() - ] - const [actions] = await Promise.all(mutations) - const newProjects = actions.map((action, idx) => { - const tags = ['#private'] - const isArchived = action.isComplete || false - if (isArchived) { - tags.push('#archived') - } - return { - id: action.id, - agendaId: action.agendaId, - content: action.content, - createdAt: action.createdAt, - isArchived, - sortOrder: idx, // meh, so they have to resort, oh well - status: 'active', - tags, - teamId: action.teamMemberId.split('::')[1], - teamMemberId: action.teamMemberId, - updatedAt: action.updatedAt - } - }) - - await r - .table('Project') - .insert(newProjects) - .run() - - try { - await r.tableDrop('Action').run() - } catch (e) { - // - } - - const indices = [ - r - .table('Project') - .indexCreate('tags', {multi: true}) - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } - - const waitIndices = [ - r - .table('Project') - .indexWait('tags') - .run() - ] - await Promise.all(waitIndices) -} - -exports.down = async (r) => { - const tables = [r.tableCreate('Action').run()] - try { - await Promise.all(tables) - } catch (e) { - // - } - const projectsToConvert = await r - .table('Project') - .getAll('#private', {index: 'tags'}) - .run() - const actions = projectsToConvert.map((project, idx) => ({ - id: project.id, - content: project.content, - userId: project.userId, - teamMemberId: project.teamMemberId, - isComplete: project.tags.includes('#archived'), - createdAt: project.createdAt, - updatedAt: project.updatedAt, - sortOrder: idx, - agendaId: project.agendaId - })) - - await r - .table('Action') - .insert(actions) - .run() - - const mutations = [ - r - .table('Project') - .update((project) => ({ - isArchived: r.branch(project('tags').contains('#archived'), true, false) - })) - .run() - ] - - await Promise.all(mutations) - - const indices = [ - r - .table('Project') - .indexDrop('tags') - .run(), - r - .table('Action') - .indexCreate('userId') - .run(), - r - .table('Action') - .indexCreate('teamMemberId') - .run(), - r - .table('Action') - .indexCreate('agendaId') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - // ignore - } - await r - .table('Project') - .replace(r.row.without('tags')) - .run() -} diff --git a/packages/server/database/migrations/20170515134300-fixTaggedContent.js b/packages/server/database/migrations/20170515134300-fixTaggedContent.js deleted file mode 100644 index eac07d65a5f..00000000000 --- a/packages/server/database/migrations/20170515134300-fixTaggedContent.js +++ /dev/null @@ -1,33 +0,0 @@ -exports.up = async (r) => { - const projects = await r - .table('Project') - .pluck('id', 'content', 'tags') - .run() - const promises = [] - projects.forEach((project) => { - let contentWithTag = project.content || '' - project.tags.forEach((tag) => { - if (contentWithTag.indexOf(tag) === -1) { - contentWithTag += ` ${tag}` - } - }) - if (contentWithTag !== project.content) { - promises.push( - r - .table('Project') - .get(project.id) - .update({content: contentWithTag}) - .run() - ) - } - }) - try { - await Promise.all(promises) - } catch (e) { - console.log('ERR', e) - } -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20170516165400-backfillInvoices.js b/packages/server/database/migrations/20170516165400-backfillInvoices.js deleted file mode 100644 index 21d5afd7928..00000000000 --- a/packages/server/database/migrations/20170516165400-backfillInvoices.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -import stripe from '../../billing/stripe' - -const fetchAllInvoices = async () => { - const stripeInvoices = [] - const options = {limit: 100} - - for (let i = 0; i < 100; i++) { - if (i > 0) { - options.starting_after = stripeInvoices[stripeInvoices.length - 1].id - } - const invoiceLines = await stripe.invoices.list(options) // eslint-disable-line no-await-in-loop - stripeInvoices.push(...invoiceLines.data) - if (!invoiceLines.has_more) break - } - return stripeInvoices -} - -exports.up = async (r) => { - if (process.env.NODE_ENV !== 'production') { - console.warn('NODE_ENV is testing or devving. Not backfilling invoices') - return - } - - // invoiceCreated has been refactored so this migration won't work anymore, which is great. it served its purpose - try { - const handleInvoiceCreated = require('../../billing/handlers/invoiceCreated').default - const stripeInvoices = await fetchAllInvoices() - const invoiceIdsInDB = await r - .table('Invoice')('id') - .run() - const invoicesToHandle = stripeInvoices.filter((invoice) => !invoiceIdsInDB.includes(invoice.id)) - for (let i = 0; i < invoicesToHandle.length; i++) { - const invoice = invoicesToHandle[i] - await handleInvoiceCreated(invoice.id) // eslint-disable-line no-await-in-loop - } - } catch (e) { - // noop - } -} -*/ -exports.up = async (r) => { - // invoices where migrated years ago and the legacy stripe logic was removed in #6161 -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20170522164500-markdownToHTML.js b/packages/server/database/migrations/20170522164500-markdownToHTML.js deleted file mode 100644 index 3070c897ce9..00000000000 --- a/packages/server/database/migrations/20170522164500-markdownToHTML.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * These packages relied on things that were part of react 15 but not react 16, so they are all broken - * Since we no longer need them, it's easier to comment everything out so we can clean up our package.json #1386 - * - */ -// import {convertFromHTML, ContentState, convertToRaw, convertFromRaw, SelectionState} from 'draft-js'; -// import MarkdownIt from 'markdown-it'; -// import emoji from 'markdown-it-emoji'; -// import jsdom from 'jsdom'; -// import toMarkdown from 'to-markdown'; -// import {stateToHTML} from 'draft-js-export-html'; -// import entitizeText from 'universal/utils/draftjs/entitizeText'; -// import getTagsFromEntityMap from 'universal/utils/draftjs/getTagsFromEntityMap'; - -// const options = { -// breaks: true, -// linkify: true, -// typographer: true -// }; - -exports.up = async () => { - // const dom = new jsdom.JSDOM(''); - // global.window = dom.window; - // global.document = dom.window.document; - // global.navigator = dom.window.navigator; - // global.HTMLElement = dom.window.HTMLElement; - // global.HTMLAnchorElement = dom.window.HTMLAnchorElement; - // global.HTMLImageElement = dom.window.HTMLImageElement; - // - // const md = new MarkdownIt(options); - // md.use(emoji); - // - // const projects = await r.table('Project').pluck('id', 'content'); - // const updates = projects.map((project) => { - // const blocksFromHTML = convertFromHTML(md.render(project.content || '')); - // const contentState = ContentState.createFromBlockArray( - // blocksFromHTML.contentBlocks, - // blocksFromHTML.entityMap, - // ); - // const selectionState = new SelectionState({ - // anchorKey: contentState.getFirstBlock().getKey(), - // anchorOffset: 0, - // focusKey: contentState.getLastBlock().getKey(), - // focusOffset: contentState.getLastBlock().getLength(), - // isBackward: false, - // hasFocus: false - // }); - // const nextContentState = entitizeText(contentState, selectionState) || contentState; - // const raw = convertToRaw(nextContentState); - // const tags = getTagsFromEntityMap(raw.entityMap); - // const rawString = JSON.stringify(raw); - // return r.table('Project').get(project.id).update({content: rawString, tags}).run(); - // }); - // try { - // await Promise.all(updates); - // } catch (e) { - // console.log('ERR', e); - // } -} - -exports.down = async () => { - // const dom = new jsdom.JSDOM(''); - // global.window = dom.window; - // global.document = dom.window.document; - // global.navigator = dom.window.navigator; - // global.HTMLElement = dom.window.HTMLElement; - // global.HTMLAnchorElement = dom.window.HTMLAnchorElement; - // global.HTMLImageElement = dom.window.HTMLImageElement; - // - // const projects = await r.table('Project').pluck('id', 'content'); - // const updates = projects.map((project) => { - // let raw; - // try { - // raw = JSON.parse(project.content); - // } catch (e) { - // return undefined; - // } - // if (!raw) return undefined; - // const contentState = convertFromRaw(raw); - // const html = stateToHTML(contentState); - // const markdown = toMarkdown(html); - // return r.table('Project').get(project.id).update({content: markdown}).run(); - // }); - // try { - // await Promise.all(updates); - // } catch (e) { - // // noop - // } -} diff --git a/packages/server/database/migrations/20170628152000-addSlack.js b/packages/server/database/migrations/20170628152000-addSlack.js deleted file mode 100644 index 5cd896a9f66..00000000000 --- a/packages/server/database/migrations/20170628152000-addSlack.js +++ /dev/null @@ -1,36 +0,0 @@ -exports.up = async (r) => { - const tables = [r.tableCreate('Provider').run(), r.tableCreate('SlackIntegration').run()] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } - const indices = [ - r - .table('Provider') - .indexCreate('teamIds', {multi: true}) - .run(), - r - .table('Provider') - .indexCreate('providerUserId') - .run(), - r - .table('SlackIntegration') - .indexCreate('teamId') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(indices)') - } -} - -exports.down = async (r) => { - const tables = [r.tableDrop('SlackIntegration').run(), r.tableDrop('Provider').run()] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } -} diff --git a/packages/server/database/migrations/20170714185200-addGitHub.js b/packages/server/database/migrations/20170714185200-addGitHub.js deleted file mode 100644 index 4868fd673c5..00000000000 --- a/packages/server/database/migrations/20170714185200-addGitHub.js +++ /dev/null @@ -1,32 +0,0 @@ -exports.up = async (r) => { - const tables = [r.tableCreate('GitHubIntegration').run()] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } - const indices = [ - r - .table('GitHubIntegration') - .indexCreate('teamId') - .run(), - r - .table('GitHubIntegration') - .indexCreate('userIds', {multi: true}) - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(indices)') - } -} - -exports.down = async (r) => { - const tables = [r.tableDrop('GitHubIntegration').run()] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } -} diff --git a/packages/server/database/migrations/20170714185201-removeEmptyContent.js b/packages/server/database/migrations/20170714185201-removeEmptyContent.js deleted file mode 100644 index 644ba24a130..00000000000 --- a/packages/server/database/migrations/20170714185201-removeEmptyContent.js +++ /dev/null @@ -1,10 +0,0 @@ -exports.up = async (r) => { - r.table('Project') - .filter((doc) => doc('content').match('"?blocks"?:\\s*\\[\\s*]')) - .delete() - .run() -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20170810164300-addProjectIntegrationId.js b/packages/server/database/migrations/20170810164300-addProjectIntegrationId.js deleted file mode 100644 index 60752f63dc7..00000000000 --- a/packages/server/database/migrations/20170810164300-addProjectIntegrationId.js +++ /dev/null @@ -1,35 +0,0 @@ -exports.up = async (r) => { - const indices = [ - r - .table('Project') - .indexCreate('integrationId', (project) => project('integration')('integrationId')) - .run(), - r - .table('GitHubIntegration') - .indexCreate('nameWithOwner') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(indices)') - } -} - -exports.down = async (r) => { - const indices = [ - r - .table('Project') - .indexDrop('integrationId') - .run(), - r - .table('GitHubIntegration') - .indexDrop('nameWithOwner') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } -} diff --git a/packages/server/database/migrations/20170821152300-providerTeamIdsToTeamIdjs.js b/packages/server/database/migrations/20170821152300-providerTeamIdsToTeamIdjs.js deleted file mode 100644 index 0578345511d..00000000000 --- a/packages/server/database/migrations/20170821152300-providerTeamIdsToTeamIdjs.js +++ /dev/null @@ -1,72 +0,0 @@ -exports.up = async (r) => { - const tables = [ - r - .table('Provider') - .replace((row) => { - return row - .merge({ - teamId: row('teamIds')(0).default(null), - isActive: row('teamIds') - .count() - .ne(0) - }) - .without('teamIds') - }) - .run() - ] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } - const indices = [ - r - .table('Provider') - .indexDrop('teamIds') - .run(), - r - .table('Provider') - .indexCreate('teamId') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(indices)') - } -} - -exports.down = async (r) => { - const tables = [ - r - .tableDrop('Provider') - .replace((row) => { - return row - .merge({ - teamIds: r.branch(row('teamId'), [row('teamId')], []) - }) - .without('teamId', 'isActive') - }) - .run() - ] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } - const indices = [ - r - .table('Provider') - .indexCreate('teamIds', {multi: true}) - .run(), - r - .table('Provider') - .indexDrop('teamId') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(indices)') - } -} diff --git a/packages/server/database/migrations/20170824163600-removeBadTeamMembers.js b/packages/server/database/migrations/20170824163600-removeBadTeamMembers.js deleted file mode 100644 index a231fab98f9..00000000000 --- a/packages/server/database/migrations/20170824163600-removeBadTeamMembers.js +++ /dev/null @@ -1,60 +0,0 @@ -exports.up = async (r) => { - const changes = await r - .table('User') - .pluck('id', 'tms') - .filter((doc) => - doc('tms') - .count() - .ne(0) - ) - .concatMap((userDoc) => { - return r.map(userDoc('tms'), (teamId) => - userDoc('id') - .add('::') - .add(teamId) - ) - }) - .coerceTo('array') - .do((teamMemberIds) => { - return r - .table('TeamMember') - .getAll(r.args(teamMemberIds), {index: 'id'}) - .filter({isNotRemoved: false}) - .pluck('teamId', 'userId') - .coerceTo('array') - }) - .forEach((badTeamMember) => { - return r - .table('User') - .get(badTeamMember('userId')) - .update( - (doc) => ({ - tms: doc('tms').difference([badTeamMember('teamId')]) - }), - {returnChanges: true} - ) - })('changes') - .default([]) - .run() - - if (changes.length === 0) return - - // reduce it to 1 call per userId - const smallestTMSperUser = changes.reduce((userObj, change) => { - const {id: userId, tms} = change.new_val - if (!userObj[userId] || userObj[userId].length < tms) { - userObj[userId] = tms - } - return userObj - }, {}) - - const userIds = Object.keys(smallestTMSperUser) - - console.log(`Removed ${userIds.length} users from ${changes.length} teams`) - const affectedUsers = changes.map((change) => change.new_val.preferredName).join() - console.log('affected users: ', affectedUsers) -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20170831142900-addUserEmailIndex.js b/packages/server/database/migrations/20170831142900-addUserEmailIndex.js deleted file mode 100644 index 1680e95a8c0..00000000000 --- a/packages/server/database/migrations/20170831142900-addUserEmailIndex.js +++ /dev/null @@ -1,21 +0,0 @@ -exports.up = async (r) => { - try { - await r - .table('User') - .indexCreate('email') - .run() - } catch (e) { - console.log('Exception during index creation') - } -} - -exports.down = async (r) => { - try { - await r - .table('User') - .indexDrop('email') - .run() - } catch (e) { - console.log('Exception during index drop') - } -} diff --git a/packages/server/database/migrations/20170906195000-removeNotificationVarList.js b/packages/server/database/migrations/20170906195000-removeNotificationVarList.js deleted file mode 100644 index 0f999fb4ac6..00000000000 --- a/packages/server/database/migrations/20170906195000-removeNotificationVarList.js +++ /dev/null @@ -1,51 +0,0 @@ -exports.up = async (r) => { - // these are the only notification types in the prod database as of 9/6/17 - const tables = [ - r - .table('Notification') - .filter({type: 'REQUEST_NEW_USER'}) - .replace((row) => { - return row - .merge({ - inviterUserId: row('varList')(0), - inviterName: row('varList')(1), - inviteeEmail: row('varList')(2), - teamId: row('varList')(3), - teamName: row('varList')(4) - }) - .without('varList') - }) - .run(), - r - .table('Notification') - .filter({type: 'TEAM_ARCHIVED'}) - .replace((row) => { - return row - .merge({ - teamName: row('varList')(0) - }) - .without('varList') - }) - .run(), - r - .table('Notification') - .filter((row) => row('type').match('^TRIAL_')) - .replace((row) => { - return row - .merge({ - trialExpiresAt: row('varList')(0) - }) - .without('varList') - }) - .run() - ] - try { - await Promise.all(tables) - } catch (e) { - console.log('Exception during Promise.all(tables)') - } -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20170918163900-keepOrgApprovals.js b/packages/server/database/migrations/20170918163900-keepOrgApprovals.js deleted file mode 100644 index ab6badce6b0..00000000000 --- a/packages/server/database/migrations/20170918163900-keepOrgApprovals.js +++ /dev/null @@ -1,19 +0,0 @@ -exports.up = async (r) => { - const now = new Date() - await r - .table('OrgApproval') - .update({ - updatedAt: now, - status: 'PENDING' - }) - .run() -} - -exports.down = async (r) => { - await r - .table('OrgApproval') - .replace((row) => { - return row.without('updatedAt', 'status') - }) - .run() -} diff --git a/packages/server/database/migrations/20170921170700-fixInvitationExpiry.js b/packages/server/database/migrations/20170921170700-fixInvitationExpiry.js deleted file mode 100644 index 675776c2fd7..00000000000 --- a/packages/server/database/migrations/20170921170700-fixInvitationExpiry.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.up = async (r) => { - r.table('Invitation') - .update((doc) => { - return r.branch( - doc('tokenExpiration') - .typeOf() - .eq('NUMBER') - .default(false), - {tokenExpiration: r.epochTime(doc('tokenExpiration'))}, - null - ) - }) - .run() -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20170926142800-freemium.js b/packages/server/database/migrations/20170926142800-freemium.js deleted file mode 100644 index 04ab06079a5..00000000000 --- a/packages/server/database/migrations/20170926142800-freemium.js +++ /dev/null @@ -1,53 +0,0 @@ -exports.up = async (r) => { - await r({ - updatedUsers: r.table('User').replace((doc) => { - return doc.without('trialOrg') - }), - removedNotifications: r - .table('Notification') - .filter((row) => row('type').match('^TRIAL_')) - .delete(), - updatedTeamsAndOrgs: r.table('Organization').forEach((org) => { - return r.branch( - org('creditCard')('last4') - .default(null) - .eq(null), - // FREE accounts - r - .table('Organization') - .get(org('id')) - .replace((row) => - row.merge({tier: 'personal'}).without('stripeId', 'stripeSubscriptionId') - ) - .do(() => { - return r - .table('Team') - .getAll(org('id'), {index: 'orgId'}) - .update({ - tier: 'personal', - isPaid: true - }) - }), - // PREMIUM accounts - r - .table('Organization') - .get(org('id')) - .update({ - tier: 'pro' - }) - .do(() => { - return r - .table('Team') - .getAll(org('id'), {index: 'orgId'}) - .update({ - tier: 'pro' - }) - }) - ) - }) - }).run() -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20171013142900-changeProjectIndex.js b/packages/server/database/migrations/20171013142900-changeProjectIndex.js deleted file mode 100644 index 8159ded9d96..00000000000 --- a/packages/server/database/migrations/20171013142900-changeProjectIndex.js +++ /dev/null @@ -1,17 +0,0 @@ -exports.up = async (r) => { - await r({ - newIdx: r - .table('Project') - .indexCreate('teamIdUpdatedAt', (row) => [row('teamId'), row('updatedAt')]), - oldIdx: r.table('Project').indexDrop('teamIdCreatedAt') - }).run() -} - -exports.down = async (r) => { - await r({ - newIdx: r - .table('Project') - .indexCreate('teamIdCreatedAt', (row) => [row('teamId'), row('createdAt')]), - oldIdx: r.table('Project').indexDrop('teamIdUpdatedAt') - }).run() -} diff --git a/packages/server/database/migrations/20171023195700-checkinQuestion.js b/packages/server/database/migrations/20171023195700-checkinQuestion.js deleted file mode 100644 index cb4af70b0b7..00000000000 --- a/packages/server/database/migrations/20171023195700-checkinQuestion.js +++ /dev/null @@ -1,30 +0,0 @@ -import {ContentState, convertToRaw} from 'draft-js' - -exports.up = async (r) => { - const teamsWithActiveMeetings = await r - .table('Team') - .filter((team) => - team('checkInQuestion') - .default(null) - .ne(null) - ) - .pluck('id', 'checkInQuestion') - .run() - - await Promise.all( - teamsWithActiveMeetings.map((team) => { - const contentState = ContentState.createFromText(team.checkInQuestion) - const raw = convertToRaw(contentState) - const checkInQuestion = JSON.stringify(raw) - return r - .table('Team') - .get(team.id) - .update({checkInQuestion}) - .run() - }) - ) -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20171026160540-removeBillingFromPersonalTeams.js b/packages/server/database/migrations/20171026160540-removeBillingFromPersonalTeams.js deleted file mode 100644 index 2864c3cd338..00000000000 --- a/packages/server/database/migrations/20171026160540-removeBillingFromPersonalTeams.js +++ /dev/null @@ -1,12 +0,0 @@ -exports.up = (r) => { - const billingFields = ['stripeId', 'stripeSubscriptionId', 'periodEnd', 'periodStart'] - return r - .table('Organization') - .filter({tier: 'personal'}) - .replace((org) => org.without(...billingFields).merge({creditCard: {}})) - .run() -} - -exports.down = () => { - // noop -} diff --git a/packages/server/database/migrations/20171115161524-fixRemovedTeamMember.js b/packages/server/database/migrations/20171115161524-fixRemovedTeamMember.js deleted file mode 100644 index c89829b5931..00000000000 --- a/packages/server/database/migrations/20171115161524-fixRemovedTeamMember.js +++ /dev/null @@ -1,12 +0,0 @@ -exports.up = async (r) => { - await r - .table('Project') - .update((project) => ({ - userId: project('teamMemberId').split('::')(0) - })) - .run() -} - -exports.down = () => { - // noop -} diff --git a/packages/server/database/migrations/20171214122751-fixTeamTier.js b/packages/server/database/migrations/20171214122751-fixTeamTier.js deleted file mode 100644 index 9f2c5c0c9bc..00000000000 --- a/packages/server/database/migrations/20171214122751-fixTeamTier.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = (r) => { - return r - .table('Team') - .update( - (team) => ({ - tier: r.table('Organization').get(team('orgId'))('tier') - }), - {nonAtomic: true} - ) - .run() -} - -exports.down = () => { - // noop -} diff --git a/packages/server/database/migrations/20180117153603-softTeamMembers.js b/packages/server/database/migrations/20180117153603-softTeamMembers.js deleted file mode 100644 index 6400da5f286..00000000000 --- a/packages/server/database/migrations/20180117153603-softTeamMembers.js +++ /dev/null @@ -1,112 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableCreate('SoftTeamMember').run() - } catch (e) { - // noop - } - try { - await Promise.all([ - r - .table('SoftTeamMember') - .indexCreate('email') - .run(), - r - .table('SoftTeamMember') - .indexCreate('teamId') - .run(), - r - .table('TeamMember') - .indexDrop('teamMemberId') - .run(), - r - .table('TeamMember') - .indexCreate('assigneeId') - .run(), - r - .table('Project') - .indexDrop('teamMemberId') - .run(), - r - .table('Project') - .indexCreate('assigneeId') - .run() - ]) - } catch (e) { - // noop - } - try { - await r({ - project: r.table('Project').replace((row) => { - return row - .merge({ - assigneeId: row('teamMemberId'), - isSoftProject: false - }) - .without('teamMemberId') - }), - history: r.table('ProjectHistory').replace((row) => { - return row.merge({ - assigneeId: row('teamMemberId'), - isSoftProject: false - }) - }) - }).run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await r.tableDrop('SoftTeamMember').run() - } catch (e) { - // noop - } - try { - await r - .table('TeamMember') - .indexDrop('assigneeId') - .run() - await r - .table('TeamMember') - .indexCreate('teamMemberId') - .run() - await r - .table('Project') - .indexDrop('assigneeId') - .run() - await r - .table('Project') - .indexCreate('teamMemberId') - .run() - } catch (e) { - // noop - } - - try { - await r - .table('Project') - .filter({isSoftProject: true}) - .delete() - .run() - await r - .table('Project') - .update((row) => ({ - teamMemberId: row('assigneeId') - })) - .run() - await r - .table('ProjectHistory') - .filter({isSoftProject: true}) - .delete() - .run() - await r - .table('ProjectHistory') - .update((row) => ({ - teamMemberId: row('assigneeId') - })) - .run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180206135107-renameProjectToTask.js b/packages/server/database/migrations/20180206135107-renameProjectToTask.js deleted file mode 100644 index af896289f0a..00000000000 --- a/packages/server/database/migrations/20180206135107-renameProjectToTask.js +++ /dev/null @@ -1,129 +0,0 @@ -exports.up = async (r) => { - // rename the Project/ProjectHistory tables - await r.table('Project').wait().run() - await r.table('Project').config().update({name: 'Task'}).run() - await r.table('Task').wait().run() - await r.table('ProjectHistory').config().update({name: 'TaskHistory'}).run() - await r.table('TaskHistory').indexDrop('projectIdUpdatedAt').run() - await r - .table('TaskHistory') - .indexCreate('taskIdUpdatedAt', (row) => [row('taskId'), row('updatedAt')]) - .run() - // replace Task.isSoftProject with Task.isSoftTask - await r - .table('Task') - .update((task) => task.merge({isSoftTask: task('isSoftProject')}).without('isSoftProject')) - .run() - - // replace TaskHistory.projectId with TaskHistory.taskId - await r - .table('TaskHistory') - .filter(r.row.hasFields('projectId')) - .update((taskHistory) => - taskHistory.merge({taskId: taskHistory('projectId')}).without('projectId') - ) - .run() - - // replace Meeting.projects with Meeting.tasks - await r - .table('Meeting') - .filter(r.row.hasFields('projects')) - .update((meeting) => meeting.merge({tasks: meeting('projects')}).without('projects')) - .run() - - // replace Meeting.invitees.projects with Meeting.invitees.tasks - await r - .table('Meeting') - .filter(r.row.hasFields('invitees')) - .update((meeting) => - meeting.merge({ - invitees: meeting('invitees').map((invitee) => - invitee.merge({tasks: invitee('projects')}).without('projects') - ) - }) - ) - .run() - - // replace Notification.projectId wth Notification.taskId, and PROJECT_INVOLVES notification type to TASK_INVOLVES - await r - .table('Notification') - .filter( - r.row.hasFields('projectId').and((row) => { - return row('type').eq('PROJECT_INVOLVES') - }) - ) - .update((notification) => - notification - .merge({ - taskId: notification('projectId'), - type: 'TASK_INVOLVES' - }) - .without('projectId') - ) - .run() -} - -exports.down = async (r) => { - // rename the Task/TaskHistory tables - await r.table('Task').config().update({name: 'Project'}).run() - await r.table('TaskHistory').config().update({name: 'ProjectHistory'}).run() - await r.table('ProjectHistory').indexDrop('taskIdUpdatedAt').run() - await r - .table('ProjectHistory') - .indexCreate('projectIdUpdatedAt', (row) => [row('projectId'), row('updatedAt')]) - .run() - - // replace Project.isSoftTask with Project.isSoftProject - await r - .table('Project') - .update((project) => - project.merge({isSoftProject: project('isSoftTask')}).without('isSoftTask') - ) - .run() - - // replace ProjectHistory.taskId with ProjectHistory.projectId - await r - .table('ProjectHistory') - .filter(r.row.hasFields('taskId')) - .update((projectHistory) => - projectHistory.merge({projectId: projectHistory('taskId')}).without('taskId') - ) - - // replace Meeting.projects with Meeting.tasks - await r - .table('Meeting') - .filter(r.row.hasFields('tasks')) - .update((meeting) => meeting.merge({projects: meeting('tasks')}).without('tasks')) - .run() - - // replace Meeting.invitees.projects with Meeting.invitees.tasks - await r - .table('Meeting') - .filter(r.row.hasFields('invitees')) - .update((meeting) => - meeting.merge({ - invitees: meeting('invitees').map((invitee) => - invitee.merge({projects: invitee('tasks')}).without('tasks') - ) - }) - ) - .run() - - // replace Notification.projectId wth Notification.taskId, and PROJECT_INVOLVES notification type to TASK_INVOLVES - await r - .table('Notification') - .filter( - r.row.hasFields('taskId').and(function (row) { - return row('type').eq('TASK_INVOLVES') - }) - ) - .update((notification) => - notification - .merge({ - projectId: notification('taskId'), - type: 'PROJECT_INVOLVES' - }) - .without('taskId') - ) - .run() -} diff --git a/packages/server/database/migrations/20180212124328-retro.js b/packages/server/database/migrations/20180212124328-retro.js deleted file mode 100644 index f9c25c85ec4..00000000000 --- a/packages/server/database/migrations/20180212124328-retro.js +++ /dev/null @@ -1,95 +0,0 @@ -import {RETRO_PHASE_ITEM} from 'parabol-client/utils/constants' - -exports.up = async (r) => { - let counter = 0 - try { - await Promise.all([ - r.tableCreate('CustomPhaseItem').run(), - r.tableCreate('NewMeeting').run(), - r.tableCreate('RetroThought').run(), - r.tableCreate('RetroThoughtGroup').run() - ]) - } catch (e) { - // noop - } - try { - await Promise.all([ - r - .table('CustomPhaseItem') - .indexCreate('teamId') - .run(), - r - .table('NewMeeting') - .indexCreate('teamId') - .run(), - r - .table('RetroThought') - .indexCreate('meetingId') - .run(), - r - .table('RetroThought') - .indexCreate('thoughtGroupId') - .run(), - r - .table('RetroThoughtGroup') - .indexCreate('meetingId') - .run() - // r.table('RetroThoughtGroup').indexCreate('teamId'), - ]) - } catch (e) { - // noop - } - try { - const teamIds = await r - .table('Team')('id') - .run() - const inserts = [] - teamIds.forEach((teamId) => { - inserts.push( - { - id: String(counter++), - type: RETRO_PHASE_ITEM, - isActive: true, - teamId, - title: 'Positive', - question: 'What’s working?' - }, - { - id: String(counter++), - type: RETRO_PHASE_ITEM, - isActive: true, - teamId, - title: 'Negative', - question: 'Where did you get stuck?' - }, - { - id: String(counter++), - type: RETRO_PHASE_ITEM, - isActive: true, - teamId, - title: 'Change', - question: 'What might we do differently next time?' - } - ) - }) - await r - .table('CustomPhaseItem') - .insert(inserts) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await Promise.all([ - r.tableDrop('CustomPhaseItem').run(), - r.tableDrop('NewMeeting').run(), - r.tableDrop('RetroThought').run(), - r.tableDrop('RetroThoughtGroup').run() - ]) - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180226074116-meetingSettings.js b/packages/server/database/migrations/20180226074116-meetingSettings.js deleted file mode 100644 index 119a878b0b0..00000000000 --- a/packages/server/database/migrations/20180226074116-meetingSettings.js +++ /dev/null @@ -1,70 +0,0 @@ -import { - ACTION, - AGENDA_ITEMS, - CHECKIN, - DISCUSS, - FIRST_CALL, - GROUP, - LAST_CALL, - LOBBY, - RETROSPECTIVE, - SUMMARY, - UPDATES, - VOTE -} from 'parabol-client/utils/constants' - -exports.up = async (r) => { - let counter = 0 - counter++ - try { - await Promise.all([r.tableCreate('MeetingSettings').run()]) - } catch (e) { - // noop - } - try { - await Promise.all([ - r - .table('MeetingSettings') - .indexCreate('teamId') - .run() - ]) - } catch (e) { - // noop - } - try { - const teamIds = await r - .table('Team')('id') - .run() - const inserts = [] - teamIds.forEach((teamId) => { - inserts.push( - { - id: String(counter++), - meetingType: RETROSPECTIVE, - teamId, - phases: [LOBBY, CHECKIN, 'think', GROUP, VOTE, DISCUSS, SUMMARY] - }, - { - id: String(counter++), - meetingType: ACTION, - teamId, - phases: [LOBBY, CHECKIN, UPDATES, FIRST_CALL, AGENDA_ITEMS, LAST_CALL, SUMMARY] - } - ) - }) - await r - .table('MeetingSettings') - .insert(inserts) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await Promise.all([r.tableDrop('MeetingSettings').run()]) - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180301081900-addOrgTierIndex.js b/packages/server/database/migrations/20180301081900-addOrgTierIndex.js deleted file mode 100644 index 8af52c26d67..00000000000 --- a/packages/server/database/migrations/20180301081900-addOrgTierIndex.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.up = async (r) => { - await r - .table('Organization') - .indexCreate('tier') - .run() -} - -exports.down = async (r) => { - await r - .table('Orgainzation') - .indexDrop('tier') - .run() -} diff --git a/packages/server/database/migrations/20180305191107-customPhaseItems.js b/packages/server/database/migrations/20180305191107-customPhaseItems.js deleted file mode 100644 index 17648f8d76f..00000000000 --- a/packages/server/database/migrations/20180305191107-customPhaseItems.js +++ /dev/null @@ -1,80 +0,0 @@ -import { LOBBY, SUMMARY } from 'parabol-client/utils/constants' - -exports.up = async (r) => { - try { - await r - .table('CustomPhaseItem') - .filter({ - title: 'Change' - }) - .delete() - .run() - } catch (e) { - // noop - } - - try { - await r - .table('CustomPhaseItem') - .replace((customPhaseItem) => { - return customPhaseItem - .merge({ - phaseItemType: customPhaseItem('type') - }) - .without('type') - }) - .run() - } catch (e) { - // noop - } - - try { - await r - .table('MeetingSettings') - .replace((settings) => { - return settings - .merge({ - phaseTypes: settings('phases').difference([LOBBY, SUMMARY]) - }) - .without('phases') - }) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - // DOES NOT REPLACE REMOVED "CHANGED" CATEGORY BECAUSE A NEW ID WOULD CAUSE SADNESS - try { - await r - .table('CustomPhaseItem') - .replace((customPhaseItem) => { - return customPhaseItem - .merge({ - type: customPhaseItem('type') - }) - .without('phaseItemType') - }) - .run() - } catch (e) { - // noop - } - try { - await r - .table('MeetingSettings') - .replace((settings) => { - return ( - settings - // don't add lobby & summary back in, we don't know where they go - .merge({ - phases: settings('phaseTypes') - }) - .without('phaseTypes') - ) - }) - .run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180319122615-retroReflection.js b/packages/server/database/migrations/20180319122615-retroReflection.js deleted file mode 100644 index eface1d456b..00000000000 --- a/packages/server/database/migrations/20180319122615-retroReflection.js +++ /dev/null @@ -1,65 +0,0 @@ -import { - CHECKIN, - DISCUSS, - GROUP, - LOBBY, - REFLECT, - RETROSPECTIVE, - SUMMARY, - VOTE -} from 'parabol-client/utils/constants' - -exports.up = async (r) => { - try { - await Promise.all([ - r.tableDrop('RetroThought').run(), - r.tableDrop('RetroThoughtGroup').run(), - r.tableCreate('RetroReflection').run(), - r.tableCreate('RetroReflectionGroup').run() - ]) - } catch (e) { - // noop - } - try { - await Promise.all([ - r - .table('RetroReflection') - .indexCreate('meetingId') - .run(), - r - .table('RetroReflection') - .indexCreate('reflectionGroupId') - .run(), - r - .table('RetroReflectionGroup') - .indexCreate('meetingId') - .run() - ]) - } catch (e) { - // noop - } - try { - await r - .table('MeetingSettings') - .filter({ meetingType: RETROSPECTIVE }) - .update({ - phaseTypes: [LOBBY, CHECKIN, REFLECT, GROUP, VOTE, DISCUSS, SUMMARY] - }) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await Promise.all([ - r.tableCreate('RetroThought').run(), - r.tableCreate('RetroThoughtGroup').run(), - r.tableDrop('RetroReflection').run(), - r.tableDrop('RetroReflectionGroup').run() - ]) - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180320152455-voteSettings.js b/packages/server/database/migrations/20180320152455-voteSettings.js deleted file mode 100644 index 7bf4518e82c..00000000000 --- a/packages/server/database/migrations/20180320152455-voteSettings.js +++ /dev/null @@ -1,56 +0,0 @@ -import { RETROSPECTIVE } from 'parabol-client/utils/constants' - -exports.up = async (r) => { - try { - await r.tableCreate('MeetingMember').run() - } catch (e) { - // noop - } - try { - await Promise.all([ - r - .table('MeetingMember') - .indexCreate('meetingId') - .run(), - r - .table('MeetingMember') - .indexCreate('teamId') - .run(), - r - .table('MeetingMember') - .indexCreate('userId') - .run() - ]) - } catch (e) { - // noop - } - try { - await r - .table('MeetingSettings') - .filter({ meetingType: RETROSPECTIVE }) - .update({ - totalVotes: 5, - maxVotesPerGroup: 3 - }) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await r - .table('MeetingSettings') - .filter({ meetingType: RETROSPECTIVE }) - .replace((settings) => settings.without('totalVotes', 'maxVotesPerGroup')) - .run() - } catch (e) { - // noop - } - try { - await r.tableDrop('MeetingMember').run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180320200910-fix-retroReflection.js b/packages/server/database/migrations/20180320200910-fix-retroReflection.js deleted file mode 100644 index a940222725b..00000000000 --- a/packages/server/database/migrations/20180320200910-fix-retroReflection.js +++ /dev/null @@ -1,26 +0,0 @@ -import { - CHECKIN, - DISCUSS, - GROUP, - REFLECT, - RETROSPECTIVE, - VOTE -} from 'parabol-client/utils/constants' - -exports.up = async (r) => { - try { - await r - .table('MeetingSettings') - .filter({ meetingType: RETROSPECTIVE }) - .update({ - phaseTypes: [CHECKIN, REFLECT, GROUP, VOTE, DISCUSS] - }) - .run() - } catch (e) { - // noop - } -} - -exports.down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20180413152455-voteSettingsV2.js b/packages/server/database/migrations/20180413152455-voteSettingsV2.js deleted file mode 100644 index 615e3026844..00000000000 --- a/packages/server/database/migrations/20180413152455-voteSettingsV2.js +++ /dev/null @@ -1,57 +0,0 @@ -import { RETROSPECTIVE } from 'parabol-client/utils/constants' - -// the first voteSettings did not take (possible merge conflict?) trying again -exports.up = async (r) => { - try { - await r.tableCreate('MeetingMember').run() - } catch (e) { - // noop - } - try { - await Promise.all([ - r - .table('MeetingMember') - .indexCreate('meetingId') - .run(), - r - .table('MeetingMember') - .indexCreate('teamId') - .run(), - r - .table('MeetingMember') - .indexCreate('userId') - .run() - ]) - } catch (e) { - // noop - } - try { - await r - .table('MeetingSettings') - .filter({ meetingType: RETROSPECTIVE }) - .update({ - totalVotes: 5, - maxVotesPerGroup: 3 - }) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await r - .table('MeetingSettings') - .filter({ meetingType: RETROSPECTIVE }) - .replace((settings) => settings.without('totalVotes', 'maxVotesPerGroup')) - .run() - } catch (e) { - // noop - } - try { - await r.tableDrop('MeetingMember').run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180509162156-addFreeRetros.js b/packages/server/database/migrations/20180509162156-addFreeRetros.js deleted file mode 100644 index 4554787eb58..00000000000 --- a/packages/server/database/migrations/20180509162156-addFreeRetros.js +++ /dev/null @@ -1,33 +0,0 @@ -exports.up = async (r) => { - try { - await r - .table('Organization') - .update((org) => { - return r.branch( - org('tier').eq('pro'), - { - retroMeetingsOffered: 0, - retroMeetingsRemaining: 0 - }, - { - retroMeetingsOffered: 3, - retroMeetingsRemaining: 3 - } - ) - }) - .run() - } catch (e) { - // noop - } -} - -exports.down = async (r) => { - try { - await r - .table('Organization') - .replace((org) => org.without('retroMeetingsOffered', 'retroMeetingsRemaining')) - .run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20180904093953-addRetroTemplates.js b/packages/server/database/migrations/20180904093953-addRetroTemplates.js deleted file mode 100644 index 944d897cf15..00000000000 --- a/packages/server/database/migrations/20180904093953-addRetroTemplates.js +++ /dev/null @@ -1,142 +0,0 @@ -import {RETRO_PHASE_ITEM} from 'parabol-client/utils/constants' - -exports.up = async (r) => { - let counter = 199 - try { - await Promise.all([r.tableCreate('ReflectTemplate').run()]) - } catch (e) { } - try { - await Promise.all([ - r - .table('ReflectTemplate') - .indexCreate('teamId') - .run(), - r - .table('CustomPhaseItem') - .indexCreate('teamId') - .run() - ]) - } catch (e) { } - - const now = new Date() - const makeTemplate = (name, teamId) => ({ - id: String(counter++), - createdAt: now, - isActive: true, - name, - teamId, - updatedAt: now - }) - - const templateNames = [ - 'Working & Stuck', - 'Glad, Sad, Mad', - 'Liked, Learned, Lacked, Longed for', - 'Start Stop Continue', - 'Sailboat' - ] - - const gladSadMadPrompts = ['Glad', 'Sad', 'Mad'] - const fourLsPrompts = ['Liked', 'Learned', 'Lacked', 'Longed for'] - const startStopContPrompts = ['Start', 'Stop', 'Continue'] - const sailboatPrompts = ['Wind in the sails', 'Anchors', 'Risks'] - - const makePrompt = (teamId, templateId, question, sortOrder) => ({ - id: String(counter++), - createdAt: now, - phaseItemType: RETRO_PHASE_ITEM, - isActive: true, - sortOrder, - teamId, - updatedAt: now, - templateId, - question, - title: question - }) - - try { - // insert all templates - const teamIds = await r - .table('Team')('id') - .run() - - // make templates - const templatesByTeamId = {} - const templateInserts = [] - teamIds.forEach((teamId) => { - templatesByTeamId[teamId] = templateNames.map((name) => makeTemplate(name, teamId)) - templateInserts.push(...templatesByTeamId[teamId]) - }) - await r - .table('ReflectTemplate') - .insert(templateInserts) - .run() - - // put existing prompts into a template - const retrosCreatedAtDate = new Date('02/12/2018') - - const updatedPhaseItemPromises = teamIds.map((teamId) => { - const templateId = templatesByTeamId[teamId][0].id - return r({ - phaseItemUpdates: r - .table('CustomPhaseItem') - .getAll(teamId, {index: 'teamId'}) - .update((row) => ({ - templateId, - createdAt: retrosCreatedAtDate, - updatedAt: retrosCreatedAtDate, - sortOrder: r.branch(row('question').eq('What’s working?'), 0, 1) - })), - settingsUpdates: r - .table('MeetingSettings') - .getAll(teamId, {index: 'teamId'}) - .update({ - selectedTemplateId: templateId - }) - }).run() - }) - await Promise.all(updatedPhaseItemPromises) - - // create new prompts - const phaseItemInserts = [] - teamIds.forEach((teamId) => { - // skip the existing working/stuck template - const [, gladSadMad, fourL, startStopCont, sail] = templatesByTeamId[teamId] - const glads = gladSadMadPrompts.map((question, idx) => - makePrompt(teamId, gladSadMad.id, question, idx) - ) - const fourLs = fourLsPrompts.map((question, idx) => - makePrompt(teamId, fourL.id, question, idx) - ) - const starts = startStopContPrompts.map((question, idx) => - makePrompt(teamId, startStopCont.id, question, idx) - ) - const sailboats = sailboatPrompts.map((question, idx) => - makePrompt(teamId, sail.id, question, idx) - ) - phaseItemInserts.push(...glads, ...fourLs, ...starts, ...sailboats) - }) - await r - .table('CustomPhaseItem') - .insert(phaseItemInserts) - .run() - } catch (e) { } -} - -exports.down = async (r) => { - try { - await Promise.all([r.tableDrop('ReflectTemplate').run()]) - } catch (e) { } - try { - const retrosCreatedAtDate = new Date('02/12/2018') - await r - .table('CustomPhaseItem') - .filter((row) => row('createdAt').ne(retrosCreatedAtDate)) - .delete() - .run() - await r - .table('CustomPhaseItem') - .replace((r) => r.row.without('createdAt', 'updatedAt', 'templateId')) - .run() - } catch (e) { } -} diff --git a/packages/server/database/migrations/20181212100647-invitationsv2.js b/packages/server/database/migrations/20181212100647-invitationsv2.js deleted file mode 100644 index 63675dcbfe2..00000000000 --- a/packages/server/database/migrations/20181212100647-invitationsv2.js +++ /dev/null @@ -1,31 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableCreate('TeamInvitation').run() - } catch (e) { - // noop - } - try { - await r({ - token: r - .table('TeamInvitation') - .indexCreate('token') - .run(), - email: r - .table('TeamInvitation') - .indexCreate('email') - .run(), - teamId: r - .table('TeamInvitation') - .indexCreate('teamId') - .run() - }) - } catch (e) {} -} - -exports.down = async (r) => { - try { - await r.tableDrop('TeamInvitation').run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20181220152050-newOrgUser.js b/packages/server/database/migrations/20181220152050-newOrgUser.js deleted file mode 100644 index 073fbf7eaf2..00000000000 --- a/packages/server/database/migrations/20181220152050-newOrgUser.js +++ /dev/null @@ -1,80 +0,0 @@ - -exports.up = async (r) => { - let counter = 256 - try { - await r.tableCreate('OrganizationUser').run() - } catch (e) { - // noop - } - try { - await r({ - userId: r - .table('OrganizationUser') - .indexCreate('userId') - .run(), - orgId: r - .table('OrganizationUser') - .indexCreate('orgId') - .run() - }) - } catch (e) { } - try { - const orgs = await r - .table('Organization') - .pluck('id', 'createdAt', 'orgUsers') - .run() - const organizationUsers = [] - orgs.forEach((org) => { - org.orgUsers.forEach((orgUser) => { - organizationUsers.push({ - id: String(counter++), - inactive: orgUser.inactive || false, - joinedAt: org.createdAt, - newUserUntil: org.createdAt, - orgId: org.id, - removedAt: null, - role: orgUser.role || null, - userId: orgUser.id - }) - }) - }) - await r({ - organizationUsers: r - .table('OrganizationUser') - .insert(organizationUsers) - .run(), - users: r - .table('User') - .replace(r.row.without('userOrgs')) - .run(), - orgs: r - .table('Organization') - .replace(r.row.without('orgUsers')) - .run(), - userIdx: r - .table('User') - .indexDrop('userOrgs') - .run(), - orgIdx: r - .table('Organization') - .indexDrop('orgUsers') - .run() - }) - } catch (e) { } -} - -exports.down = async (r) => { - try { - await r.tableDrop('OrganizationUser').run() - await r - .table('User') - .indexCreate('userOrgs') - .run() - await r - .table('Organization') - .indexCreate('orgUsers') - .run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20181221095933-addTimeline.js b/packages/server/database/migrations/20181221095933-addTimeline.js deleted file mode 100644 index d5d4ac065e2..00000000000 --- a/packages/server/database/migrations/20181221095933-addTimeline.js +++ /dev/null @@ -1,103 +0,0 @@ -import { - COMPLETED_ACTION_MEETING, - COMPLETED_RETRO_MEETING, - JOINED_PARABOL -} from '../../graphql/types/TimelineEventTypeEnum' - -exports.up = async (r) => { - let counter = 432 - try { - await r.tableCreate('TimelineEvent').run() - } catch (e) { } - try { - await r - .table('TimelineEvent') - .indexCreate('userIdCreatedAt', (row) => [row('userId'), row('createdAt')]) - .run() - } catch (e) { } - - const {users, completedActionMeetings, completedRetroMeetings} = await r({ - users: r - .table('User') - .pluck('id', 'createdAt', 'tms') - .coerceTo('array'), - completedActionMeetings: r - .table('Meeting') - .pluck('id', 'teamId', 'endedAt') - .merge((meeting) => ({ - type: COMPLETED_ACTION_MEETING, - orgId: r - .table('Team') - .get(meeting('teamId'))('orgId') - .default(null) - })) - .filter((meeting) => meeting('orgId').ne(null)) - .coerceTo('array'), - completedRetroMeetings: r - .table('NewMeeting') - .pluck('id', 'teamId', 'endedAt') - .merge((meeting) => ({ - type: COMPLETED_RETRO_MEETING, - orgId: r - .table('Team') - .get(meeting('teamId'))('orgId') - .default(null) - })) - .filter((meeting) => meeting('orgId').ne(null)) - .coerceTo('array') - }).run() - - const completedMeetings = [...completedActionMeetings, ...completedRetroMeetings] - - // account created - const events = [] - events.push( - ...users.map((user) => { - return { - id: String(counter++), - createdAt: user.createdAt, - interactionCount: 0, - seenCount: 0, - type: JOINED_PARABOL, - userId: user.id - } - }) - ) - - // meetings completed - const usersByTeamId = {} - users.forEach((user) => { - if (!user.tms) return - user.tms.forEach((teamId) => { - usersByTeamId[teamId] = usersByTeamId[teamId] || [] - usersByTeamId[teamId].push(user.id) - }) - }) - - completedMeetings.forEach((meeting) => { - const userIds = usersByTeamId[meeting.teamId] - if (!userIds) return - const userEvents = userIds.map((userId) => ({ - id: String(counter++), - createdAt: meeting.endedAt, - interactionCount: 0, - seenCount: 0, - type: meeting.type, - userId, - teamId: meeting.teamId, - orgId: meeting.orgId, - meetingId: meeting.id - })) - events.push(...userEvents) - }) - await r - .table('TimelineEvent') - .insert(events) - .run() -} - -exports.down = async (r) => { - try { - await r.tableDrop('TimelineEvent').run() - } catch (e) { } -} diff --git a/packages/server/database/migrations/20181221124242-newFeatures.js b/packages/server/database/migrations/20181221124242-newFeatures.js deleted file mode 100644 index 6db4f5080e3..00000000000 --- a/packages/server/database/migrations/20181221124242-newFeatures.js +++ /dev/null @@ -1,25 +0,0 @@ -exports.up = async (r) => { - try { - await Promise.all([r.tableCreate('SuggestedAction').run(), r.tableCreate('NewFeature').run()]) - } catch (e) {} - try { - await Promise.all([ - r - .table('SuggestedAction') - .indexCreate('userId') - .run() - // r.table('NewFeature').indexCreate('number'), - ]) - } catch (e) {} - // try { - // await r.table('User').update({ - // broadcastNumber: 1 - // }) - // } catch (e) {} -} - -exports.down = async (r) => { - try { - await Promise.all([r.tableDrop('SuggestedAction').run(), r.tableDrop('NewFeature').run()]) - } catch (e) {} -} diff --git a/packages/server/database/migrations/20190305202636-removeLegacyInvite.js b/packages/server/database/migrations/20190305202636-removeLegacyInvite.js deleted file mode 100644 index 33665045802..00000000000 --- a/packages/server/database/migrations/20190305202636-removeLegacyInvite.js +++ /dev/null @@ -1,28 +0,0 @@ -exports.up = async (r) => { - try { - await Promise.all([r.tableDrop('OrgApproval').run(), r.tableDrop('Invitation').run()]) - } catch (e) {} - - const OLD_TYPES = [ - 'ADD_TO_TEAM', - 'DENY_NEW_USER', - 'INVITEE_APPROVED', - 'JOIN_TEAM', - 'REJOIN_TEAM', - 'REQUEST_NEW_USER', - 'TEAM_INVITE' - ] - try { - await r - .table('Notification') - .filter((notification) => r(OLD_TYPES).contains(notification('type'))) - .delete() - .run() - } catch (e) {} -} - -exports.down = async (r) => { - try { - await Promise.all([r.tableCreate('OrgApproval').run(), r.tableCreate('Invitation').run()]) - } catch (e) {} -} diff --git a/packages/server/database/migrations/20190325150049-jira.js b/packages/server/database/migrations/20190325150049-jira.js deleted file mode 100644 index 95cafe198a4..00000000000 --- a/packages/server/database/migrations/20190325150049-jira.js +++ /dev/null @@ -1,33 +0,0 @@ -exports.up = async (r) => { - try { - await Promise.all([r.tableCreate('AtlassianAuth').run()]) - } catch (e) { - /**/ - } - try { - await Promise.all([ - r - .table('AtlassianAuth') - .indexCreate('userId') - .run(), - r - .table('AtlassianAuth') - .indexCreate('teamId') - .run(), - r - .table('AtlassianAuth') - .indexCreate('accountId') - .run() - ]) - } catch (e) { - /**/ - } -} - -exports.down = async (r) => { - try { - await Promise.all([r.tableDrop('AtlassianAuth').run()]) - } catch (e) { - /**/ - } -} diff --git a/packages/server/database/migrations/20190327165913-promptDescriptions.js b/packages/server/database/migrations/20190327165913-promptDescriptions.js deleted file mode 100644 index 6f10f03acca..00000000000 --- a/packages/server/database/migrations/20190327165913-promptDescriptions.js +++ /dev/null @@ -1,62 +0,0 @@ -exports.up = async (r) => { - const questions = [ - 'Glad', - 'Sad', - 'Mad', - 'Liked', - 'Learned', - 'Lacked', - 'Longed for', - 'Wind in the sails', - 'Anchors', - 'Risks', - 'Start', - 'Stop', - 'Continue', - 'What’s working?', - 'Where did you get stuck?' - ] - const descriptions = [ - 'What are you happy about?', - 'What could be improved?', - 'What are you angry or disappointed about?', - 'What went well?', - 'What did you learn?', - 'What was missing?', - 'What did you want to happen?', - 'What’s helping the team reach its goals?', - 'What’s slowing the team down in your journey?', - 'What risks may the team encounter ahead?', - 'What new behaviors should we adopt?', - 'What existing behaviors should we cease doing?', - 'What current behaviors should we keep doing?', - 'What’s helping us make progress toward our goals?', - 'What’s blocking us from achieving our goals?' - ] - try { - await Promise.all( - questions.map((question, idx) => { - return r - .table('CustomPhaseItem') - .filter({question}) - .update({ - description: descriptions[idx] - }) - .run() - }) - ) - } catch (e) { - /**/ - } -} - -exports.down = async (r) => { - try { - await r - .table('CustomPhaseItem') - .replace((row) => row.without('description')) - .run() - } catch (e) { - /**/ - } -} diff --git a/packages/server/database/migrations/20190415082651-integrationId.js b/packages/server/database/migrations/20190415082651-integrationId.js deleted file mode 100644 index 478f6cdbce9..00000000000 --- a/packages/server/database/migrations/20190415082651-integrationId.js +++ /dev/null @@ -1,99 +0,0 @@ -exports.up = async (r) => { - try { - // there are 2 old records from 2017 that have no integrationId attached, they should be removed - await r - .table('Task') - .filter(r.row('integration').ne(null)) - .filter( - r - .row('integration')('id') - .eq(null) - ) - .delete() - .run() - } catch (e) { - console.log(e) - } - - try { - await r - .table('Task') - .filter((task) => - task('integration') - .default(null) - .ne(null) - ) - .update((task) => ({ - integration: r.literal( - task('integration') - .merge({ - id: task('integration')('integrationId'), - service: 'github' - }) - .without('integrationId') - ) - })) - .run() - } catch (e) { - console.log(e) - } - - try { - await r - .table('Task') - .indexDrop('integrationId') - .run() - } catch (e) { - console.log(e) - } - - try { - await r - .table('Task') - .indexCreate('integrationId', (project) => project('integration')('id')) - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r - .table('Task') - .filter((task) => - task('integration')('id') - .default(null) - .ne(null) - ) - .update((task) => ({ - integration: task('integration') - .merge({ - integrationId: task('integration')('id'), - service: 'GitHubIntegration' - }) - .without('id') - })) - .run() - } catch (e) { - /**/ - } - - try { - await r - .table('Task') - .indexDrop('integrationId') - .run() - } catch (e) { - /**/ - } - - try { - await r - .table('Task') - .indexCreate('integrationId', (project) => project('integration')('integrationId')) - .run() - } catch (e) { - /**/ - } -} diff --git a/packages/server/database/migrations/20190425103700-removeGitHubRepos.js b/packages/server/database/migrations/20190425103700-removeGitHubRepos.js deleted file mode 100644 index 35b3d1f80dd..00000000000 --- a/packages/server/database/migrations/20190425103700-removeGitHubRepos.js +++ /dev/null @@ -1,34 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableDrop('GitHubIntegration').run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r.tableCreate('GitHubIntegration').run() - } catch (e) { - console.log(e) - } - const indices = [ - r - .table('GitHubIntegration') - .indexCreate('teamId') - .run(), - r - .table('GitHubIntegration') - .indexCreate('userIds', {multi: true}) - .run(), - r - .table('GitHubIntegration') - .indexCreate('nameWithOwner') - .run() - ] - try { - await Promise.all(indices) - } catch (e) { - console.log('Exception during Promise.all(indices)') - } -} diff --git a/packages/server/database/migrations/20190509165854-legacyMeetingEvents.js b/packages/server/database/migrations/20190509165854-legacyMeetingEvents.js deleted file mode 100644 index 0fb1a5488d0..00000000000 --- a/packages/server/database/migrations/20190509165854-legacyMeetingEvents.js +++ /dev/null @@ -1,129 +0,0 @@ -import MeetingMember from '../types/MeetingMember' -import fromTeamMemberId from 'parabol-client/utils/relay/fromTeamMemberId' -import CheckInPhase from '../types/CheckInPhase' -import UpdatesPhase from '../types/UpdatesPhase' -import GenericMeetingPhase from '../types/GenericMeetingPhase' -import AgendaItemsPhase from '../types/AgendaItemsPhase' -import Meeting from '../types/Meeting' - -/* Migrate the old Action "Meeting" type into a "NewMeeting" type and sets an isLegacy flag on the Meeting */ - -exports.up = async (r) => { - try { - const meetings = await r.table('Meeting').run() - const completedAgendaItems = await r - .table('AgendaItem') - .filter({ isActive: false }) - .pluck('id', 'createdAt') - .run() - const agendaItemswithMeetingId = completedAgendaItems.map((agendaItem) => { - const teamMeetings = meetings.filter( - (meeting) => meeting.teamId === agendaItem.teamId && meeting.endedAt >= agendaItem.createdAt - ) - teamMeetings.sort((a, b) => (a.createdAt < b.createdAt ? -1 : 1)) - const meeting = teamMeetings[0] - return { - id: agendaItem.id, - meetingId: meeting ? meeting.id : null - } - }) - const meetingMemberInserts = [] - const taskUpdates = [] - const meetingInserts = [] - meetings.forEach((meeting) => { - const { - id: meetingId, - teamId, - endedAt, - createdAt, - invitees, - facilitator, - meetingNumber, - summarySentAt - } = meeting - if (!endedAt || !invitees || invitees.length === 0) return - const tasks = meeting.tasks || [] - const facilitatorUserId = facilitator ? facilitator.split('::')[0] : null - meetingMemberInserts.push( - ...invitees.map((invitee) => { - const { id: teamMemberId, present } = invitee - const { userId } = fromTeamMemberId(teamMemberId) - const member = new MeetingMember(teamId, userId, 'action', meetingId) - member.isCheckedIn = present - member.isLegacy = true - return member - }) - ) - - taskUpdates.push( - ...tasks.map((task) => { - return { - id: task.id.substr(teamId.length + 2), - meetingId: task.status === 'done' ? null : meetingId, - doneMeetingId: task.status === 'done' ? meetingId : null - } - }) - ) - - const teamMembers = invitees.map((invitee, checkInOrder) => ({ - id: invitee.id, - checkInOrder - })) - const agendaItemIds = agendaItemswithMeetingId - .filter((agendaItem) => agendaItem.meetingId === meetingId) - .map(({ id }) => id) - const phases = [ - new CheckInPhase(teamId, meetingNumber - 1, teamMembers), - new UpdatesPhase(teamMembers), - new GenericMeetingPhase('firstcall'), - new AgendaItemsPhase(agendaItemIds), - new GenericMeetingPhase('lastcall') - ] - phases.forEach((phase) => { - phase.stages.forEach((stage) => { - stage.startAt = createdAt - stage.endAt = endedAt - }) - }) - if (!phases[0].stages[0]) { - console.log('bad phase', JSON.stringify(phases), meetingId) - } - const newMeeting = new Meeting(teamId, 'action', meetingNumber - 1, phases, facilitatorUserId) - newMeeting.createdAt = createdAt - newMeeting.endedAt = endedAt - newMeeting.summarySentAt = summarySentAt - newMeeting.id = meetingId - newMeeting.isLegacy = true - meetingInserts.push(newMeeting) - }) - await r({ - tasks: r(taskUpdates).forEach((task) => { - return r - .table('Task') - .get(task('id')) - .update({ - doneMeetingId: task('doneMeetingId'), - meetingId: task('meetingId') - }) - }), - meetingMembers: r.table('MeetingMember').insert(meetingMemberInserts), - meetings: r.table('NewMeeting').insert(meetingInserts) - }).run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r - .table('TimelineEvent') - .filter({ type: 'actionComplete' }) - .replace((row) => { - return row.merge({ meetingId: row('legacyMeetingId') }).without('legacyMeetingId') - }) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190516143948-queryMap.js b/packages/server/database/migrations/20190516143948-queryMap.js deleted file mode 100644 index e6071c5eb80..00000000000 --- a/packages/server/database/migrations/20190516143948-queryMap.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableCreate('QueryMap').run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r.tableDrop('QueryMap').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190521222803-slack.js b/packages/server/database/migrations/20190521222803-slack.js deleted file mode 100644 index 25277a1f6a6..00000000000 --- a/packages/server/database/migrations/20190521222803-slack.js +++ /dev/null @@ -1,93 +0,0 @@ - -// This deprecates the SlackIntegration table as well as all slack rows in the Provider table -exports.up = async (r) => { - let counter = 555 - try { - await Promise.all([r.tableCreate('SlackAuth').run(), r.tableCreate('SlackNotification').run()]) - } catch (e) { - /**/ - } - try { - await Promise.all([ - r - .table('SlackAuth') - .indexCreate('userId') - .run(), - r - .table('SlackAuth') - .indexCreate('teamId') - .run(), - r - .table('SlackNotification') - .indexCreate('userId') - .run(), - r - .table('SlackNotification') - .indexCreate('teamId') - .run() - ]) - } catch (e) { - /**/ - } - const slackProviders = await r - .table('Provider') - .filter({isActive: true, service: 'SlackIntegration'}) - .run() - const slackAuths = slackProviders.map((provider) => ({ - id: provider.id, - isActive: true, - createdAt: provider.createdAt, - updatedAt: provider.updatedAt, - teamId: provider.teamId, - userId: provider.userId, - accessToken: provider.accessToken, - slackTeamId: provider.teamId, - // we can retroactively grab this later, after they re-up with a new scope - // slackTeamName, - slackUserId: provider.providerUserId, - slackUserName: provider.providerUserName - })) - try { - await r - .table('SlackAuth') - .insert(slackAuths) - .run() - } catch (e) { - console.log(e) - } - - const slackIntegrations = await r - .table('SlackIntegration') - .filter({isActive: true}) - .run() - const slackNotifications = [] - slackIntegrations.forEach((integration) => { - const slackAuth = slackAuths.find((auth) => auth.teamId === integration.teamId) - if (!slackAuth) return - const notifications = ['meetingStart', 'meetingEnd'].map((event) => ({ - id: String(counter++), - channelId: integration.isActive ? integration.channelId : null, - channelName: integration.channelName, - teamId: integration.teamId, - userId: slackAuth.userId, - event - })) - slackNotifications.push(...notifications) - }) - try { - await r - .table('SlackNotification') - .insert(slackNotifications) - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await Promise.all([r.tableDrop('SlackAuth').run(), r.tableDrop('SlackNotification').run()]) - } catch (e) { - /**/ - } -} diff --git a/packages/server/database/migrations/20190528193756-removeOldMeeting.js b/packages/server/database/migrations/20190528193756-removeOldMeeting.js deleted file mode 100644 index f6266dd9ac0..00000000000 --- a/packages/server/database/migrations/20190528193756-removeOldMeeting.js +++ /dev/null @@ -1,22 +0,0 @@ -exports.up = async (r) => { - try { - await r - .table('Team') - .replace((row) => { - return row.without( - 'activeFacilitator', - 'facilitatorPhase', - 'facilitatorPhaseItem', - 'meetingPhase', - 'meetingPhaseItem' - ) - }) - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async () => { - /* noop */ -} diff --git a/packages/server/database/migrations/20190612194707-scheduledJobs.js b/packages/server/database/migrations/20190612194707-scheduledJobs.js deleted file mode 100644 index d01757fd367..00000000000 --- a/packages/server/database/migrations/20190612194707-scheduledJobs.js +++ /dev/null @@ -1,85 +0,0 @@ -import generateUID from '../../generateUID' - -exports.up = async (r) => { - try { - await r.tableCreate('ScheduledJob').run() - } catch (e) { - console.log(e) - } - try { - await r.table('ScheduledJob').indexCreate('type').run() - await r.table('ScheduledJob').indexCreate('runAt').run() - } catch (e) { - console.log(e) - } - - try { - const slackUsers = await r.table('SlackAuth').filter({isActive: true}).run() - const slackNotifications = await r - .table('SlackNotification') - .pluck('userId', 'teamId', 'channelId') - .distinct() - .run() - const stageCompleteNotifications = slackUsers.map((slackUser) => { - const {userId, teamId} = slackUser - return { - userId, - teamId, - channelId: null, - event: 'MEETING_STAGE_TIME_LIMIT_END', - id: generateUID() - } - }) - const stageReadyNotifications = slackUsers.map((slackUser) => { - const {userId, teamId} = slackUser - const teamMemberNotification = slackNotifications.find( - (notification) => notification.teamId === teamId && notification.userId === userId - ) - const channelId = (teamMemberNotification && teamMemberNotification.channelId) || null - return new SlackNotification({ - userId, - teamId, - channelId, - event: 'MEETING_STAGE_TIME_LIMIT_START' - }) - }) - const authUpdates = slackUsers.map((slackUser) => { - const {userId, teamId} = slackUser - const teamMemberNotification = slackNotifications.find( - (notification) => - notification.teamId === teamId && notification.userId === userId && notification.channelId - ) - return { - id: slackUser.id, - channelId: (teamMemberNotification && teamMemberNotification.channelId) || null - } - }) - const records = [...stageCompleteNotifications, ...stageReadyNotifications] - await r - .table('SlackNotification') - .filter({event: 'meetingStageTimeLimit'}) - .update({event: 'MEETING_STAGE_TIME_LIMIT_END'}) - .run() - await r.table('SlackNotification').insert(records).run() - await r(authUpdates) - .forEach((auth) => { - return r - .table('SlackAuth') - .get(auth('id')) - .update({ - defaultTeamChannelId: auth('channelId') - }) - }) - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r.tableDrop('ScheduledJob').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190626105609-removeSoftTeamMembers.js b/packages/server/database/migrations/20190626105609-removeSoftTeamMembers.js deleted file mode 100644 index d8cd415f831..00000000000 --- a/packages/server/database/migrations/20190626105609-removeSoftTeamMembers.js +++ /dev/null @@ -1,38 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableDrop('SoftTeamMember').run() - } catch (e) { - console.log(e) - } - try { - await r - .table('Task') - .filter({isSoftTask: true}) - .delete() - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r.tableCreate('SoftTeamMember').run() - } catch (e) { - console.log(e) - } - try { - await Promise.all([ - r - .table('SoftTeamMember') - .indexCreate('email') - .run(), - r - .table('SoftTeamMember') - .indexCreate('teamId') - .run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190709134611-meetingFacilitatorIdx.js b/packages/server/database/migrations/20190709134611-meetingFacilitatorIdx.js deleted file mode 100644 index 001098a3692..00000000000 --- a/packages/server/database/migrations/20190709134611-meetingFacilitatorIdx.js +++ /dev/null @@ -1,21 +0,0 @@ -exports.up = async (r) => { - try { - await r - .table('NewMeeting') - .indexCreate('facilitatorUserId') - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r - .table('NewMeeting') - .indexDrop('facilitatorUserId') - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190709193044-push-invitations.js b/packages/server/database/migrations/20190709193044-push-invitations.js deleted file mode 100644 index 8a75989ee7e..00000000000 --- a/packages/server/database/migrations/20190709193044-push-invitations.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableCreate('PushInvitation').run() - } catch (e) { - console.log(e) - } - try { - await r - .table('PushInvitation') - .indexCreate('userId') - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r.tableDrop('PushInvitation').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190809124635-plaintext-reflections.js b/packages/server/database/migrations/20190809124635-plaintext-reflections.js deleted file mode 100644 index 8922eca552c..00000000000 --- a/packages/server/database/migrations/20190809124635-plaintext-reflections.js +++ /dev/null @@ -1,28 +0,0 @@ -import extractTextFromDraftString from 'parabol-client/utils/draftjs/extractTextFromDraftString' - -exports.up = async (r) => { - const reflections = await r.table('RetroReflection').run() - const reflectionsWithPlaintext = reflections.map((reflection) => ({ - id: reflection.id, - plaintextContent: extractTextFromDraftString(reflection.content) - })) - await r(reflectionsWithPlaintext) - .forEach((reflection) => { - return r - .table('RetroReflection') - .get(reflection('id')) - .update({ - plaintextContent: reflection('plaintextContent') - }) - }) - .run() -} - -exports.down = async (r) => { - await r - .table('RetroReflection') - .replace((row) => { - return row.without('plaintextContent') - }) - .run() -} diff --git a/packages/server/database/migrations/20190818101532-renameBillingLeader.js b/packages/server/database/migrations/20190818101532-renameBillingLeader.js deleted file mode 100644 index 6b1fb777093..00000000000 --- a/packages/server/database/migrations/20190818101532-renameBillingLeader.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = async (r) => { - try { - await r - .table('OrganizationUser') - .filter({role: 'billingLeader'}) - .update({role: 'BILLING_LEADER'}) - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r - .table('OrganizationUser') - .filter({role: 'BILLING_LEADER'}) - .update({role: 'billingLeader'}) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190904182024-saml.js b/packages/server/database/migrations/20190904182024-saml.js deleted file mode 100644 index 9a4ebedc885..00000000000 --- a/packages/server/database/migrations/20190904182024-saml.js +++ /dev/null @@ -1,23 +0,0 @@ -exports.up = async (r) => { - try { - await r.tableCreate('SAML').run() - } catch (e) { - console.log(e) - } - try { - await r - .table('SAML') - .indexCreate('domain') - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r.tableDrop('SAML').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190909183628-null-cc.js b/packages/server/database/migrations/20190909183628-null-cc.js deleted file mode 100644 index 8f97787d12a..00000000000 --- a/packages/server/database/migrations/20190909183628-null-cc.js +++ /dev/null @@ -1,52 +0,0 @@ -exports.up = async (r) => { - try { - await r - .table('Organization') - .filter({creditCard: {}}) - .update({creditCard: null}) - .run() - } catch (e) { - console.log(e) - } - try { - await r - .table('Invoice') - .replace((row) => - row - .merge({ - tier: 'pro', - nextPeriodCharges: row('nextMonthCharges').merge({interval: 'month'}) - }) - .without('nextMonthCharges') - ) - .run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await r - .table('Organization') - .filter({creditCard: null}) - .update({creditCard: {}}) - .run() - } catch (e) { - console.log(e) - } - try { - await r - .table('Invoice') - .replace((row) => - row - .merge({ - nextMonthCharges: row('nextPeriodCharges').without('interval') - }) - .without('nextMonthCharges', 'tier') - ) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20190912093945-remove-legacy-tables.ts b/packages/server/database/migrations/20190912093945-remove-legacy-tables.ts deleted file mode 100644 index 8e77db23e6f..00000000000 --- a/packages/server/database/migrations/20190912093945-remove-legacy-tables.ts +++ /dev/null @@ -1,25 +0,0 @@ -exports.up = async (r) => { - try { - await Promise.all([ - r.tableDrop('Meeting').run(), - r.tableDrop('Outcome').run(), - r - .branch(r.tableList().contains('AtlassianProject'), r.tableDrop('AtlassianProject'), null) - .run() - ]) - } catch (e) { - console.log(e) - } -} - -exports.down = async (r) => { - try { - await Promise.all([ - r.tableCreate('Meeting').run(), - r.tableCreate('AtlassianProject').run(), - r.tableCreate('Outcome').run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20191111140628-meetingNames.ts b/packages/server/database/migrations/20191111140628-meetingNames.ts deleted file mode 100644 index 081747dbf8f..00000000000 --- a/packages/server/database/migrations/20191111140628-meetingNames.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r - .table('NewMeeting') - .update((row) => ({ - name: r.branch( - row('meetingType').eq('retrospective'), - r('Retro #').add(row('meetingNumber').coerceTo('string')), - r('Action meeting #').add(row('meetingNumber').coerceTo('string')) - ) - })) - .run() -} - -export const down = async function (r: R) { - await r - .table('NewMeeting') - .replace((row) => row.without('name')) - .run() -} diff --git a/packages/server/database/migrations/20191120141523-byeAuth0.ts b/packages/server/database/migrations/20191120141523-byeAuth0.ts deleted file mode 100644 index 754290d1664..00000000000 --- a/packages/server/database/migrations/20191120141523-byeAuth0.ts +++ /dev/null @@ -1,74 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await Promise.all([ - r.tableCreate('FailedAuthRequest').run(), - r.tableCreate('PasswordResetRequest').run() - ]) - await Promise.all([ - r.table('FailedAuthRequest').indexCreate('ip').run(), - r.table('FailedAuthRequest').indexCreate('email').run(), - r.table('PasswordResetRequest').indexCreate('ip').run(), - r.table('PasswordResetRequest').indexCreate('email').run(), - r.table('PasswordResetRequest').indexCreate('token').run() - ]) - } catch (e) { - console.log(e) - } - - await r - .table('User') - .update((user) => ({ - identities: user('identities').map((identity) => { - return r.branch( - identity('connection').eq('Username-Password-Authentication'), - { - id: identity('user_id'), - isEmailVerified: false, - type: 'LOCAL' - }, - { - id: identity('user_id'), - isEmailVerified: true, - type: 'GOOGLE' - } - ) - }) - })) - .run() -} - -export const down = async function (r: R) { - try { - await Promise.all([ - r.tableDrop('FailedAuthRequest').run(), - r.tableDrop('PasswordResetRequest').run() - ]) - } catch (e) { - console.log(e) - } - - await r - .table('User') - .update((user) => ({ - identities: user('identities').map((identity) => { - return r.branch( - identity('type').eq('LOCAL'), - { - user_id: identity('id'), - connection: 'Username-Password-Authentication', - isSocial: false, - provider: 'auth0' - }, - { - user_id: identity('id'), - connection: 'google-oauth2', - isSocial: true, - provider: 'google-oauth2' - } - ) - }) - })) - .run() -} diff --git a/packages/server/database/migrations/20200103130450-shortMassInvite.ts b/packages/server/database/migrations/20200103130450-shortMassInvite.ts deleted file mode 100644 index 09f78e4c2ab..00000000000 --- a/packages/server/database/migrations/20200103130450-shortMassInvite.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.tableCreate('MassInvitation').run() - await r.table('MassInvitation').indexCreate('teamMemberId').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.tableDrop('MassInvitation').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200108113244-reactji.ts b/packages/server/database/migrations/20200108113244-reactji.ts deleted file mode 100644 index ad938a2f021..00000000000 --- a/packages/server/database/migrations/20200108113244-reactji.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.table('RetroReflection').update({reactjis: []}).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('RetroReflection') - .replace((row) => row.without('reactjis')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200113155150-topTier.ts b/packages/server/database/migrations/20200113155150-topTier.ts deleted file mode 100644 index 099d67d18ea..00000000000 --- a/packages/server/database/migrations/20200113155150-topTier.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('User') - .update( - (user) => ({ - tier: r - .table('OrganizationUser') - .getAll(user('id'), {index: 'userId'}) - .filter({removedAt: null})('orgId') - .coerceTo('array') - .distinct() - .do((orgIds) => - r.table('Organization').getAll(r.args(orgIds))('tier').distinct().coerceTo('array') - ) - .do((tiers) => { - return r.branch( - tiers.contains('enterprise'), - 'enterprise', - tiers.contains('pro'), - 'pro', - 'personal' - ) - }) - }), - {nonAtomic: true} - ) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('User') - .replace((row) => row.without('tier')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200122143529-lastMeetingType.ts b/packages/server/database/migrations/20200122143529-lastMeetingType.ts deleted file mode 100644 index 1658316d2e5..00000000000 --- a/packages/server/database/migrations/20200122143529-lastMeetingType.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.table('Team').update({lastMeetingType: 'retrospective'}).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('Team') - .replace((row) => row.without('lastMeetingType')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200131085921-requireVerifiedEmail.ts b/packages/server/database/migrations/20200131085921-requireVerifiedEmail.ts deleted file mode 100644 index 571056175c8..00000000000 --- a/packages/server/database/migrations/20200131085921-requireVerifiedEmail.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await Promise.all([ - r.tableCreate('SecureDomain').run(), - r.tableCreate('EmailVerification').run() - ]) - } catch (e) { - console.log(e) - } - try { - await Promise.all([ - r.table('SecureDomain').indexCreate('domain').run(), - r.table('EmailVerification').indexCreate('token').run(), - r.table('EmailVerification').indexCreate('email').run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await Promise.all([r.tableDrop('SecureDomain').run(), r.tableDrop('EmailVerification').run()]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200202171128-notificationsV2.ts b/packages/server/database/migrations/20200202171128-notificationsV2.ts deleted file mode 100644 index b42e566a941..00000000000 --- a/packages/server/database/migrations/20200202171128-notificationsV2.ts +++ /dev/null @@ -1,108 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - // delete notifications without owners - await r - .table('Notification') - .filter({userIds: [null]}) - .delete() - .run() - - // set all to unread - await r.table('Notification').update({status: 'UNREAD'}).run() - - //turn archived into CLICKED - await r - .table('Notification') - .filter({isArchived: true}) - .replace((row) => row.merge({status: 'CLICKED'}).without('isArchived')) - .run() - - // rename startAt to createdAt & userIds to userId - await r - .table('Notification') - .replace((row) => - row - .merge({ - createdAt: row('startAt'), - userId: row('userIds').nth(0).default(null) - }) - .without('startAt', 'userIds') - ) - .run() - - // add evictorUserId to all kick out notifications - await r - .table('Notification') - .filter({type: 'KICKED_OUT'}) - .update( - (row) => ({ - evictorUserId: r - .table('TeamMember') - .getAll(row('teamId'), {index: 'teamId'}) - .filter({isLead: true}) - .nth(0)('userId') - .default(row('userId')) - }), - {nonAtomic: true} - ) - .run() - - // add archivorUserId to team archived - await r - .table('Notification') - .filter({type: 'TEAM_ARCHIVED'}) - .update( - (row) => ({ - archivorUserId: r - .table('TeamMember') - .getAll(row('teamId'), {index: 'teamId'}) - .filter({isLead: true}) - .nth(0)('userId') - .default(row('userId')) - }), - {nonAtomic: true} - ) - .run() - - await Promise.all([ - r.table('Notification').indexCreate('userId').run(), - r.table('Notification').indexDrop('userIds').run(), - r.table('Notification').indexDrop('orgId').run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - //turn CLICKED into archived - await r - .table('Notification') - .filter({status: 'CLICKED'}) - .replace((row) => row.merge({isArchived: true}).without('status')) - .run() - - // rename createdAt to startAt & userId to userIds - await r - .table('Notification') - .replace((row) => - row - .merge({ - startAt: row('createdAt'), - userIds: [row('userId')] - }) - .without('createdAt', 'userId') - ) - .run() - await Promise.all([ - r.table('Notification').indexCreate('userIds', {multi: true}).run(), - r.table('Notification').indexDrop('userId').run(), - r.table('Notification').indexCreate('orgId').run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200207101941-createdByTask.ts b/packages/server/database/migrations/20200207101941-createdByTask.ts deleted file mode 100644 index 80d59d23886..00000000000 --- a/packages/server/database/migrations/20200207101941-createdByTask.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('Task') - .filter((task) => task('createdBy').default(null).eq(null)) - .update((task) => ({createdBy: task('userId')})) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function () { - // no way to selectively undo -} diff --git a/packages/server/database/migrations/20200212125426-removeTaskAssignee.ts b/packages/server/database/migrations/20200212125426-removeTaskAssignee.ts deleted file mode 100644 index 0050375eca3..00000000000 --- a/packages/server/database/migrations/20200212125426-removeTaskAssignee.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('Task').indexDrop('assigneeId').run(), - r.table('TeamMember').indexDrop('assigneeId').run() - ]) - await r - .table('Task') - .replace((row) => row.without('assigneeId')) - .run() - } catch (e) { - // no log because Task doesn't typically have assigneeId - } -} - -export const down = async function (r: R) { - try { - await r - .table('Task') - .update((row) => ({ - assigneeId: row('userId').add(row('teamId')) - })) - .run() - await Promise.all([ - r.table('Task').indexCreate('assigneeId').run(), - r.table('TeamMember').indexCreate('assigneeId').run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200212141946-comments.ts b/packages/server/database/migrations/20200212141946-comments.ts deleted file mode 100644 index 1c1196c300f..00000000000 --- a/packages/server/database/migrations/20200212141946-comments.ts +++ /dev/null @@ -1,65 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.tableCreate('Comment').run() - await Promise.all([ - r.table('Comment').indexCreate('threadId').run(), - r.table('Task').indexDrop('agendaId').run() - ]) - await r - .table('Task') - .filter((row) => row('agendaId').default(null).ne(null)) - .replace((row) => - row - .merge({ - threadId: row('agendaId'), - threadSource: 'AGENDA_ITEM' - }) - .without('agendaId') - ) - .run() - await r - .table('Task') - .filter((row) => row('reflectionGroupId').default(null).ne(null)) - .replace((row) => - row - .merge({ - threadId: row('reflectionGroupId'), - threadSource: 'REFLECTION_GROUP' - }) - .without('reflectionGroupId') - ) - .run() - - await r.table('Task').indexCreate('threadId').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.tableDrop('Comment').run() - await r.table('Task').indexDrop('threadId').run() - await r - .table('Task') - .filter((row) => row('threadId').default(null).ne(null)) - .replace((row) => - row - .merge({ - agendaId: r.branch(row('threadSource').eq('AGENDA_ITEM'), row('threadId'), null), - reflectionGroupId: r.branch( - row('threadSource').eq('REFLECTION_GROUP'), - row('threadId'), - null - ) - }) - .without('threadId', 'threadSource') - ) - .run() - await r.table('Task').indexCreate('agendaId').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200303123942-actionToCheckIn.ts b/packages/server/database/migrations/20200303123942-actionToCheckIn.ts deleted file mode 100644 index 4cc07ec413e..00000000000 --- a/packages/server/database/migrations/20200303123942-actionToCheckIn.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter((meeting) => meeting('name').match('Action meeting #')) - .update((row) => ({ - name: r('Check-in #').add(row('meetingNumber').coerceTo('string')) - })) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter((meeting) => meeting('name').match('Check-in #')) - .update((row) => ({ - name: r('Action meeting #').add(row('meetingNumber').coerceTo('string')) - })) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200319183146-betterHooks.ts b/packages/server/database/migrations/20200319183146-betterHooks.ts deleted file mode 100644 index 4d61a1ae8a6..00000000000 --- a/packages/server/database/migrations/20200319183146-betterHooks.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.table('InvoiceItemHook').indexCreate('stripeSubscriptionId').run() - await r.table('InvoiceItemHook').indexDrop('userId').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('InvoiceItemHook').indexDrop('stripeSubscriptionId').run() - await r.table('InvoiceItemHook').indexCreate('userId').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200323143644-retroevents.ts b/packages/server/database/migrations/20200323143644-retroevents.ts deleted file mode 100644 index 32c080e5b66..00000000000 --- a/packages/server/database/migrations/20200323143644-retroevents.ts +++ /dev/null @@ -1,61 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - const getThreadIds = (row) => - r.args( - r - .table('RetroReflectionGroup') - .getAll(row('id'), {index: 'meetingId'}) - .filter({isActive: true})('id') - .coerceTo('array') as any - ) - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .filter((row) => row('endedAt').default(null).ne(null)) - .update( - (row) => ({ - commentCount: r - .table('Comment') - .getAll(getThreadIds(row), {index: 'threadId'}) - .filter({isActive: true}) - .count() - .default(0), - taskCount: r - .table('Task') - .getAll(getThreadIds(row), {index: 'threadId'}) - .count() - .default(0), - topicCount: r - .table('RetroReflectionGroup') - .getAll(row('id'), {index: 'meetingId'}) - .filter({isActive: true}) - .count() - .default(0), - reflectionCount: r - .table('RetroReflection') - .getAll(row('id'), {index: 'meetingId'}) - .filter({isActive: true}) - .count() - .default(0) - }), - {nonAtomic: true} - ) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .replace((row) => row.without('commentCount', 'topicCount', 'reflectionCount', 'taskCount')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200325104319-meetingVotes.ts b/packages/server/database/migrations/20200325104319-meetingVotes.ts deleted file mode 100644 index ed8ffd9e39e..00000000000 --- a/packages/server/database/migrations/20200325104319-meetingVotes.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .update({ - totalVotes: 5, - maxVotesPerGroup: 3 - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .replace((row) => row.without('maxVotes', 'maxVotesPerGroup')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200410115039-GQLRequest.ts b/packages/server/database/migrations/20200410115039-GQLRequest.ts deleted file mode 100644 index d85cf8ac090..00000000000 --- a/packages/server/database/migrations/20200410115039-GQLRequest.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.tableCreate('GQLRequest').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.tableDrop('GQLRequest').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200505120000-timelineEventIsActive.ts b/packages/server/database/migrations/20200505120000-timelineEventIsActive.ts deleted file mode 100644 index bb972b559b0..00000000000 --- a/packages/server/database/migrations/20200505120000-timelineEventIsActive.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('TimelineEvent') - .update({ - isActive: true - }) - .run() - - await r.table('TimelineEvent').indexCreate('meetingId').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('TimelineEvent') - .replace((row) => row.without('isActive')) - .run() - - await r.table('TimelineEvent').indexDrop('meetingId').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200518150457-colorTemplates.ts b/packages/server/database/migrations/20200518150457-colorTemplates.ts deleted file mode 100644 index 43f2b3e0eaf..00000000000 --- a/packages/server/database/migrations/20200518150457-colorTemplates.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {PALETTE} from 'parabol-client/styles/paletteV3' -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - const questions = [ - 'Glad', - 'Sad', - 'Mad', - 'Liked', - 'Learned', - 'Lacked', - 'Longed for', - 'Wind in the sails', - 'Anchors', - 'Risks', - 'Start', - 'Stop', - 'Continue', - 'What’s working?', - 'Where did you get stuck?' - ] - const questionColors = [ - PALETTE.PROMPT_GREEN, - PALETTE.PROMPT_BLUE, - PALETTE.PROMPT_RED, - PALETTE.PROMPT_GREEN, - PALETTE.PROMPT_BLUE, - PALETTE.PROMPT_ORANGE, - PALETTE.PROMPT_VIOLET, - PALETTE.PROMPT_GREEN, - PALETTE.PROMPT_BLUE, - PALETTE.PROMPT_RED, - PALETTE.PROMPT_GREEN, - PALETTE.PROMPT_RED, - PALETTE.PROMPT_BLUE, - PALETTE.PROMPT_GREEN, - PALETTE.PROMPT_RED - ] - - const allColors = [ - PALETTE.PROMPT_GREEN, - PALETTE.PROMPT_YELLOW, - PALETTE.PROMPT_ORANGE, - PALETTE.PROMPT_RED, - PALETTE.PROMPT_BLUE, - PALETTE.PROMPT_CYAN, - PALETTE.PROMPT_VIOLET, - PALETTE.PROMPT_PINK, - PALETTE.PROMPT_LIGHT_BLUE, - PALETTE.PROMPT_LIGHT_GREEN, - PALETTE.PROMPT_PURPLE, - PALETTE.PROMPT_FUCHSIA - ] - - try { - await Promise.all( - questions.map((question, idx) => { - return r - .table('CustomPhaseItem') - .filter({question}) - .update({ - groupColor: questionColors[idx] - }) - .run() - }) - ) - } catch (e) { - console.log(e) - } - try { - const colorlessItemGroups = (await r - .table('CustomPhaseItem') - .filter((row) => row('groupColor').default(null).eq(null)) - .group('templateId')('id') - .ungroup()('reduction') - .run()) as string[][] - - const updates = [] as {id: string; color: string}[] - colorlessItemGroups.forEach((items) => { - items.forEach((itemId, idx) => { - updates.push({id: itemId, color: allColors[idx]}) - }) - }) - await r(updates) - .forEach((update) => { - return r - .table('CustomPhaseItem') - .get(update('id')) - .update({ - color: update('color') - }) - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('CustomPhaseItem') - .replace((row) => row.without('groupColor')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200528105904-orgActiveDomain.ts b/packages/server/database/migrations/20200528105904-orgActiveDomain.ts deleted file mode 100644 index 6248ceb7221..00000000000 --- a/packages/server/database/migrations/20200528105904-orgActiveDomain.ts +++ /dev/null @@ -1,99 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const GENERIC_DOMAINS = [ - 'gmail.com', - 'yahoo.com', - 'googlemail.com', - 'hotmail.com', - 'outlook.com', - 'mail.com' -] - -const isCompanyDomain = (domain) => !GENERIC_DOMAINS.includes(domain) - -const getGroupMajority = (tlds) => { - const countByDomain = {} - tlds.forEach((tld) => { - countByDomain[tld] = countByDomain[tld] || 0 - countByDomain[tld]++ - }) - let maxCount = 0 - let maxDomain = '' - Object.keys(countByDomain).forEach((tld) => { - const curCount = countByDomain[tld] - if (curCount > maxCount) { - maxCount = curCount - maxDomain = tld - } - }) - return maxDomain -} - -const getDomainFromEmail = (email) => { - return email.slice(email.indexOf('@') + 1) -} - -const getActiveDomainFromEmails = (emails) => { - const tlds = emails.map(getDomainFromEmail) - const companyDomains = tlds.filter(isCompanyDomain) - return getGroupMajority(companyDomains) -} - -export const up = async function (r: R) { - try { - await r.table('Organization').indexCreate('activeDomain').run() - } catch (e) { - console.log(e) - } - - try { - const groupings = (await r - .table('OrganizationUser') - .filter({removedAt: null}) - .merge((row) => ({ - email: r.table('User').get(row('userId'))('email').default('') - })) - .group('orgId')('email') - .ungroup() - .run()) as {group: string; reduction: string[]}[] - - const updates = [] as {orgId: string; activeDomain: string}[] - - groupings.forEach((group) => { - const {group: orgId, reduction: emails} = group - const activeDomain = getActiveDomainFromEmails(emails) - if (activeDomain) { - updates.push({orgId, activeDomain}) - } - }) - await r(updates) - .forEach((update) => { - return r - .table('Organization') - .get(update('orgId')) - .update({ - activeDomain: update('activeDomain') - }) - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('Organization').indexDrop('activeDomain').run() - } catch (e) { - console.log(e) - } - - try { - await r - .table('Organization') - .replace((row) => row.without('activeDomain')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200531084145-backfillMeetingIdOnAgendaItem.ts b/packages/server/database/migrations/20200531084145-backfillMeetingIdOnAgendaItem.ts deleted file mode 100644 index 6e26673de0f..00000000000 --- a/packages/server/database/migrations/20200531084145-backfillMeetingIdOnAgendaItem.ts +++ /dev/null @@ -1,68 +0,0 @@ -const enum MeetingTypeEnum { - action = 'action', - retrospective = 'retrospective', - poker = 'poker' -} -const enum NewMeetingPhaseTypeEnum { - lobby = 'lobby', - checkin = 'checkin', - updates = 'updates', - firstcall = 'firstcall', - agendaitems = 'agendaitems', - lastcall = 'lastcall', - reflect = 'reflect', - group = 'group', - vote = 'vote', - discuss = 'discuss', - SUMMARY = 'SUMMARY', - SCOPE = 'SCOPE', - ESTIMATE = 'ESTIMATE' -} - -export const up = async function (r) { - try { - const actionMeetings = await r - .table('NewMeeting') - .filter({meetingType: MeetingTypeEnum.action}) - .run() - // TODO: depending on production data, may need to chunk this - const updates = [] as { - agendaItemId: string - meetingId: string - }[] - actionMeetings.forEach((meeting) => { - meeting.phases.forEach((phase) => { - if (phase.phaseType !== NewMeetingPhaseTypeEnum.agendaitems) return - phase.stages.forEach((stage) => { - if (stage.phaseType !== NewMeetingPhaseTypeEnum.agendaitems) return - updates.push({ - meetingId: meeting.id, - agendaItemId: stage.agendaItemId - }) - }) - }) - }) - - await r(updates) - .forEach((update) => { - return r - .table('AgendaItem') - .get(update('agendaItemId')) - .update({meetingId: update('meetingId')}) - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await r - .table('AgendaItem') - .replace((row) => row.without('meetingId')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200602211355-lowercase-emails.ts b/packages/server/database/migrations/20200602211355-lowercase-emails.ts deleted file mode 100644 index c025ad3ca9a..00000000000 --- a/packages/server/database/migrations/20200602211355-lowercase-emails.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('User') - .filter((row) => row('email').match('.*[A-Z].*')) - .filter((row) => row('email').ne('DELETED'))('id') - .coerceTo('array') - .do((userIds) => { - return r({ - user: r - .table('User') - .getAll(r.args(userIds)) - .update((row) => ({email: row('email').downcase()})), - teamMembers: r - .table('TeamMember') - .getAll(r.args(userIds), {index: 'userId'}) - .update((row) => ({ - email: row('email').downcase() - })) - }) - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function () { - // noop -} diff --git a/packages/server/database/migrations/20200610125717-cleanUsers.ts b/packages/server/database/migrations/20200610125717-cleanUsers.ts deleted file mode 100644 index 845f2e38de2..00000000000 --- a/packages/server/database/migrations/20200610125717-cleanUsers.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('User') - .replace((row) => - row.without( - 'welcomeSentAt', - 'cacheExpiresAt', - 'cachedAt', - 'emailVerified', - 'name', - 'nickname' - ) - ) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function () { - // noop -} diff --git a/packages/server/database/migrations/20200617000000-addMeetingIdIndexToAgendaItems.ts b/packages/server/database/migrations/20200617000000-addMeetingIdIndexToAgendaItems.ts deleted file mode 100644 index 14f55a994c5..00000000000 --- a/packages/server/database/migrations/20200617000000-addMeetingIdIndexToAgendaItems.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.table('AgendaItem').indexCreate('meetingId').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('AgendaItem').indexDrop('meetingId').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200629155809-mergeDuplicateUsers.ts b/packages/server/database/migrations/20200629155809-mergeDuplicateUsers.ts deleted file mode 100644 index e2a2bfeb049..00000000000 --- a/packages/server/database/migrations/20200629155809-mergeDuplicateUsers.ts +++ /dev/null @@ -1,155 +0,0 @@ -import {R} from 'rethinkdb-ts' -import User from '../types/User' - -export const up = async function (r: R) { - const updateTeamMember = async (goodUserId: string, badUserId: string) => { - // we don't want to delete the team member because the NewMeeting object - // references it in the TeamMemberStages (checkin & update stages) - // instead, we just inactivate - const {goodTeamMembers, badTeamMembers} = await r({ - goodTeamMembers: r - .table('TeamMember') - .getAll(goodUserId, {index: 'userId'}) - .coerceTo('array') as any, - badTeamMembers: r - .table('TeamMember') - .getAll(badUserId, {index: 'userId'}) - .update( - { - userId: goodUserId, - isNotRemoved: false - }, - {returnChanges: true} - )('changes')('new_val') - .default([]) as any - }).run() - - // for each bad team member, see if a good one exists on that team - // if the good one does not exist, then create it since the old in now inactive - const teamMembersToInsert = [] as any[] - badTeamMembers.forEach((badTeamMember) => { - const goodTeamMember = goodTeamMembers.find( - (teamMember) => teamMember.id === badTeamMember.id - ) - if (!goodTeamMember) { - badTeamMember.id = `${goodUserId}::${badTeamMember.teamId}` - teamMembersToInsert.push(badTeamMember) - } - }) - await r.table('TeamMember').insert(badTeamMembers).run() - // update org user - // it's possible 2 user objects could exist on the same, that's OK for now - await r - .table('OrganizationUser') - .getAll(badUserId, {index: 'userId'}) - .update({ - userId: goodUserId - }) - .run() - - // replace meeting members with updated ones - const meetingMembers = await r.table('MeetingMember').getAll(badUserId, {index: 'userId'}).run() - const updatedMeetingMembers = meetingMembers.map((meetingMember) => ({ - ...meetingMember, - id: `${goodUserId}::${meetingMember.meetingId}`, - userId: goodUserId - })) - await r.table('MeetingMember').getAll(badUserId, {index: 'userId'}).delete().run() - await r.table('MeetingMember').insert(updatedMeetingMembers).run() - - // replace team invitations - await r - .table('TeamInvitation') - .filter({invitedBy: badUserId}) - .update({invitedBy: goodUserId}) - .run() - await r - .table('Notification') - .filter({ - evictorUserId: badUserId - }) - .update({ - evictorUserId: goodUserId - }) - .run() - await r - .table('Notification') - .filter({ - archivorUserId: badUserId - }) - .update({ - archivorUserId: goodUserId - }) - .run() - } - - try { - const affectedEmails = (await r - .table('User') - .group('email') - .count() - .ungroup() - .filter((row) => row('reduction').gt(1))('group') - .filter((row) => row.ne('DELETED')) - .run()) as string[] - - const allDuplicates = [] as Promise[] - affectedEmails.forEach((email) => { - allDuplicates.push( - r.table('User').getAll(email, {index: 'email'}).orderBy('createdAt').coerceTo('array').run() - ) - }) - - const toUpdate = [] as User[] - const toDeleteIds = [] as string[] - const teamMemberUpdates = [] as Promise[] - for await (const innerArr of allDuplicates) { - const [old, ...newer] = innerArr - const {identities: oldIdentities} = old - for (const dup of newer) { - const {identities} = dup - for (const identity of identities) { - const {type} = identity - const matchingOldIdentityIdx = oldIdentities.findIndex( - (identity) => identity.type === type - ) - if (matchingOldIdentityIdx !== -1) { - oldIdentities[matchingOldIdentityIdx] = identity - } - } - old.tms = old.tms.concat(dup.tms) - old.email = dup.email ? dup.email : old.email - old.picture = dup.picture ? dup.picture : old.picture - toDeleteIds.push(dup.id) - teamMemberUpdates.push(updateTeamMember(old.id, dup.id)) - } - old.tms = Array.from(new Set(old.tms)) - toUpdate.push(old) - } - - await r(toUpdate) - .forEach((update) => { - return r - .table('User') - .get(update('id')) - .update( - { - email: update('email'), - picture: update('picture'), - tms: update('tms'), - identities: update('identities') - }, - {returnChanges: true} - ) - }) - .run() - - await r.table('User').getAll(r.args(toDeleteIds)).delete({returnChanges: true}).run() - } catch (e) { - console.log(e) - } -} - -export const down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20200701094336-addTierToOrgUser.ts b/packages/server/database/migrations/20200701094336-addTierToOrgUser.ts deleted file mode 100644 index a6f412c66fd..00000000000 --- a/packages/server/database/migrations/20200701094336-addTierToOrgUser.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - const tierToOrgIds = (await r - .table('Organization') - .group('tier') - .map((org) => org('id')) - .ungroup() - .map((group) => ({ - tier: group('group'), - orgIds: group('reduction') - })) - .run()) as {tier: string; orgIds: string[]}[] - - await r(tierToOrgIds) - .forEach((update) => { - return r - .table('OrganizationUser') - .getAll(r.args(update('orgIds') as any), {index: 'orgId'}) - .update({tier: update('tier')}) - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await r - .table('OrganizationUser') - .replace((row) => row.without('tier')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200702100758-addTierInactiveIndexOnOrgUser.ts b/packages/server/database/migrations/20200702100758-addTierInactiveIndexOnOrgUser.ts deleted file mode 100644 index 1cf70747d6e..00000000000 --- a/packages/server/database/migrations/20200702100758-addTierInactiveIndexOnOrgUser.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const up = async function (r) { - try { - await Promise.all([ - r - .table('OrganizationUser') - .indexCreate('tierInactive', [r.row('tier'), r.row('inactive')]) - .run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await Promise.all([r.table('OrganizationUser').indexDrop('tierInactive').run()]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200715162900-backfillIsActiveForCreatedTeamTimelineEvent.ts b/packages/server/database/migrations/20200715162900-backfillIsActiveForCreatedTeamTimelineEvent.ts deleted file mode 100644 index 144347cd6a4..00000000000 --- a/packages/server/database/migrations/20200715162900-backfillIsActiveForCreatedTeamTimelineEvent.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('TimelineEvent') - .filter((event) => event.hasFields('isActive').not()) - .update({ - isActive: true - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function () { - // noop -} diff --git a/packages/server/database/migrations/20200717141122-masterTemplates.ts b/packages/server/database/migrations/20200717141122-masterTemplates.ts deleted file mode 100644 index d6efd3b12ff..00000000000 --- a/packages/server/database/migrations/20200717141122-masterTemplates.ts +++ /dev/null @@ -1,417 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const createdAt = new Date('2016-06-01') - -const aGhostUser = { - id: 'aGhostUser', - preferredName: 'A Ghost', - connectedSockets: [], - email: 'love@parabol.co', - featureFlags: [], - updatedAt: createdAt, - picture: - 'https://action-files.parabol.co/production/build/v5.10.1/42342faa774f05b7626fa91ff8374e59.svg', - inactive: false, - identities: [], - createdAt, - tier: 'enterprise', - tms: 'aGhostTeam' -} - -const aGhostOrg = { - id: 'aGhostOrg', - name: 'Parabol', - picture: - 'https://action-files.parabol.co/production/build/v5.10.1/42342faa774f05b7626fa91ff8374e59.svg', - tier: 'enterprise', - createdAt, - updatedAt: createdAt -} -const aGhostTeam = { - id: 'aGhostTeam', - name: 'Parabol', - createdAt, - createdBy: 'aGhostUser', - isArchived: false, - isPaid: true, - tier: 'enterprise', - orgId: 'aGhostOrg', - isOnboardTeam: true, - updatedAt: createdAt -} - -const aGhostOrgMember = { - id: 'aGhostOrganizationUser', - inactive: false, - joinedAt: createdAt, - newUserUntil: createdAt, - orgId: 'aGhostOrg', - removedAt: null, - role: 'BILLING_LEADER', - userId: 'aGhostUser' -} - -const templates = [ - { - createdAt: createdAt, - id: 'sailboatTemplate', - isActive: true, - name: 'Sailboat', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - }, - { - createdAt: createdAt, - id: 'startStopContinueTemplate', - isActive: true, - name: 'Start, Stop, Continue', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - }, - { - createdAt: createdAt, - id: 'workingStuckTemplate', - isActive: true, - name: 'Working & Stuck', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - }, - { - createdAt: createdAt, - id: 'fourLsTemplate', - isActive: true, - name: 'Four L’s', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - }, - { - createdAt: createdAt, - id: 'gladSadMadTemplate', - isActive: true, - name: 'Glad, Sad, Mad', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - } -] - -const phaseItems = [ - { - createdAt: createdAt, - description: 'What did you learn?', - groupColor: '#5CA0E5', - id: 'promptWhatLearn', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Learned', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'fourLsTemplate', - title: 'Learned', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What was missing?', - groupColor: '#E59545', - id: 'promptWhatMissing', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Lacked', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'fourLsTemplate', - title: 'Lacked', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What’s slowing the team down in your journey?', - groupColor: '#D9D916', - id: 'promptWhatSlowing', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Anchors', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'sailboatTemplate', - title: 'Anchors', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What are you happy about?', - groupColor: '#52CC52', - id: 'promptWhatHappy', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Glad', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'gladSadMadTemplate', - title: 'Glad', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What are you angry or disappointed about?', - groupColor: '#E55C5C', - id: 'promptWhatAngry', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Mad', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'gladSadMadTemplate', - title: 'Mad', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What could be improved?', - groupColor: '#D9D916', - id: 'promptWhatImproved', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Sad', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'gladSadMadTemplate', - title: 'Sad', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What current behaviors should we keep doing?', - groupColor: '#D9D916', - id: 'promptWhatKeep', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Continue', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'startStopContinueTemplate', - title: 'Continue', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What’s helping us make progress toward our goals?', - groupColor: '#52CC52', - id: 'promptWhatHelps', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'What’s working?', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'workingStuckTemplate', - title: 'Positive', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What risks may the team encounter ahead?', - groupColor: '#E55C5C', - id: 'promptWhatRisks', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Risks', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'sailboatTemplate', - title: 'Risks', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What new behaviors should we adopt?', - groupColor: '#52CC52', - id: 'promptWhatAdopt', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Start', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'startStopContinueTemplate', - title: 'Start', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What’s helping the team reach its goals?', - groupColor: '#52CC52', - id: 'promptWhatHelpGoal', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Wind in the sails', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'sailboatTemplate', - title: 'Wind in the sails', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What existing behaviors should we cease doing?', - groupColor: '#E55C5C', - id: 'promptWhatCease', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Stop', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'startStopContinueTemplate', - title: 'Stop', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What went well?', - groupColor: '#52CC52', - id: 'promptWhatWell', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Liked', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'fourLsTemplate', - title: 'Liked', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What did you want to happen?', - groupColor: '#AC73E5', - id: 'promptWhatHappen', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Longed for', - sortOrder: 3, - teamId: 'aGhostTeam', - templateId: 'fourLsTemplate', - title: 'Longed for', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What’s blocking us from achieving our goals?', - groupColor: '#E55C5C', - id: 'promptWhatBlocking', - isActive: true, - phaseItemType: 'retroPhaseItem', - question: 'Where did you get stuck?', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'workingStuckTemplate', - title: 'Negative', - updatedAt: createdAt - } -] -export const up = async function (r: R) { - try { - // promote templateId to the root of the meeting document - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .update((row) => ({ - templateId: row('phases')( - row('phases') - .offsetsOf((row) => row('phaseType').eq('reflect')) - .nth(0) - )('promptTemplateId').default(null) - })) - .run() - await r.table('NewMeeting').indexCreate('templateId').run() - await r.table('NewMeeting').indexWait('templateId').run() - } catch (e) { - console.log(e) - } - - // delete unused templates, approx 90% of templates are unused! - try { - await r - .table('ReflectTemplate') - .filter((row) => r.table('NewMeeting').getAll(row('id'), {index: 'templateId'}).count().eq(0)) - .delete() - .run() - } catch (e) { - console.log(e) - } - - // add scope & orgId to templates - try { - await r - .table('ReflectTemplate') - .update( - (row) => ({ - scope: 'TEAM', - orgId: r.table('Team').get(row('teamId'))('orgId').default(null) - }), - {nonAtomic: true} - ) - .run() - await r.table('ReflectTemplate').indexCreate('orgId').run() - await r.table('ReflectTemplate').indexWait('orgId').run() - } catch (e) { - console.log(e) - } - - // add initial public templates - try { - await Promise.all([ - r.table('User').insert(aGhostUser).run(), - r.table('OrganizationUser').insert(aGhostOrgMember).run(), - r.table('Organization').insert(aGhostOrg).run(), - r.table('Team').insert(aGhostTeam).run(), - r.table('ReflectTemplate').insert(templates).run(), - r.table('CustomPhaseItem').insert(phaseItems).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('NewMeeting').indexDrop('templateId').run() - await r - .table('NewMeeting') - .replace((row) => row.without('templateId')) - .run() - } catch (e) { - console.log(e) - } - - try { - await r.table('ReflectTemplate').indexDrop('orgId').run() - await r - .table('ReflectTemplate') - .replace((row) => row.without('scope', 'orgId')) - .run() - } catch (e) { - console.log(e) - } - const templateIds = templates.map(({id}) => id) - const promptIds = phaseItems.map(({id}) => id) - try { - await Promise.all([ - r.table('User').get(aGhostUser.id).delete().run(), - r.table('OrganizationUser').get(aGhostOrgMember.id).delete().run(), - r.table('Organization').get(aGhostOrg.id).delete().run(), - r.table('Team').get(aGhostTeam.id).delete().run(), - r.table('ReflectTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('CustomPhaseItem').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200803121128-addTemplateDimension.ts b/packages/server/database/migrations/20200803121128-addTemplateDimension.ts deleted file mode 100644 index 6abf5eb09b0..00000000000 --- a/packages/server/database/migrations/20200803121128-addTemplateDimension.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.tableCreate('TemplateDimension').run() - - await r.table('TemplateDimension').indexCreate('templateId').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.tableDrop('TemplateDimension').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200803123551-addTemplateScale.ts b/packages/server/database/migrations/20200803123551-addTemplateScale.ts deleted file mode 100644 index fd8561b757d..00000000000 --- a/packages/server/database/migrations/20200803123551-addTemplateScale.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r.tableCreate('TemplateScale').run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.tableDrop('TemplateScale').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200804110724-refactorCustomPhaseItem.ts b/packages/server/database/migrations/20200804110724-refactorCustomPhaseItem.ts deleted file mode 100644 index c741452280c..00000000000 --- a/packages/server/database/migrations/20200804110724-refactorCustomPhaseItem.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {R} from 'rethinkdb-ts' -exports.up = async (r: R) => { - // this is going to be a BIG db hit, so delete the unnedded records first - try { - await r.table('RetroReflectionGroup').filter({isActive: false}).delete().run() - } catch (e) { - console.log(e) - } - try { - await r({ - reflection: r.table('RetroReflection').update((row) => ({promptId: row('retroPhaseItemId')})), - group: r.table('RetroReflectionGroup').update((row) => ({promptId: row('retroPhaseItemId')})) - }).run() - } catch (e) { - console.log(e) - } - - try { - await r.table('CustomPhaseItem').config().update({name: 'ReflectPrompt'}).run() - } catch (e) { - console.log(e) - } - try { - await r.table('ReflectPrompt').indexCreate('templateId').run() - } catch (e) { - console.log(e) - } -} - -exports.down = async (r: R) => { - try { - await r({ - reflection: r.table('RetroReflection').update((row) => ({retroPhaseItemId: row('promptId')})), - group: r.table('RetroReflectionGroup').update((row) => ({retroPhaseItemId: row('promptId')})) - }).run() - } catch (e) { - console.log(e) - } - try { - await r.table('ReflectPrompt').config().update({name: 'CustomPhaseItem'}).run() - } catch (e) { - console.log(e) - } - try { - await r.table('CustomPhaseItem').indexDrop('templateId').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200824105351-pokerTemplate.ts b/packages/server/database/migrations/20200824105351-pokerTemplate.ts deleted file mode 100644 index c1b0bd55664..00000000000 --- a/packages/server/database/migrations/20200824105351-pokerTemplate.ts +++ /dev/null @@ -1,158 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const createdAt = new Date('2020-08-24') -const templates = [ - { - createdAt: createdAt, - id: 'estimatedEffortTemplate', - isActive: true, - name: 'Estimated Effort', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - }, - { - createdAt: createdAt, - id: 'wsjfTemplate', - isActive: true, - name: 'Weighted Shortest Job First', - teamId: 'aGhostTeam', - updatedAt: createdAt, - scope: 'PUBLIC', - orgId: 'aGhostOrg' - } -] - -const dimensions = [ - { - id: 'eeStoryPointsDimension', - name: 'Story Points', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - scaleId: 'fibonacciScale', - createdAt, - updatedAt: createdAt - }, - { - id: 'wsjfStoryPointsDimension', - name: 'Story Points', - teamId: 'aGhostTeam', - templateId: 'wsjfTemplate', - scaleId: 'fibonacciScale', - createdAt, - updatedAt: createdAt - }, - { - id: 'wsjfStoryValueDimension', - name: 'Story Value', - teamId: 'aGhostTeam', - templateId: 'wsjfTemplate', - scaleId: 'fibonacciScale', - createdAt, - updatedAt: createdAt - } -] - -const scales = [ - { - id: 'fibonacciScale', - createdAt, - updatedAt: createdAt, - name: 'Fibonacci', - values: ['1', '2', '3', '5', '8', '13', '21', '34'], - teamId: 'aGhostTeam' - }, - { - id: 'tshirtSizeScale', - createdAt, - updatedAt: createdAt, - name: 'T-Shirt Sizes', - values: ['XS', 'SM', 'M', 'L', 'XL'], - teamId: 'aGhostTeam' - }, - { - id: 'fiveFingersScale', - createdAt, - updatedAt: createdAt, - name: 'Five Fingers', - values: ['1', '2', '3', '4', '5'], - teamId: 'aGhostTeam' - } -] - -export const up = async function (r: R) { - let counter = 654 - // all previous templates should be marked as retrospective templates - try { - await r.table('ReflectTemplate').update({type: 'retrospective'}).run() - } catch (e) { - console.log(e) - } - - // rename ReflectTemplate table to MeetingTemplate since we'll use it for both retro and poker - try { - await r.table('ReflectTemplate').config().update({name: 'MeetingTemplate'}).run() - } catch (e) { - console.log(e) - } - // add initial public templates - try { - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('TemplateDimension').insert(dimensions).run(), - r.table('TemplateScale').insert(scales).run() - ]) - } catch (e) { - console.log(e) - } - - try { - const teamIds = await r.table('Team')('id').coerceTo('array').run() - const settings = teamIds.map((teamId) => ({ - id: `settings:${teamId}:${counter++}`, - selectedTemplateId: 'estimatedEffortTemplate', - meetingType: 'poker', - teamId, - phaseTypes: ['checkin', 'SCOPE', 'ESTIMATE'] - })) - await r.table('MeetingSettings').insert(settings).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('MeetingTemplate').config().update({name: 'ReflectTemplate'}).run() - } catch (e) { - console.log(e) - } - const templateIds = templates.map(({id}) => id) - const dimensionIds = dimensions.map(({id}) => id) - const scaleIds = scales.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('TemplateDimension').getAll(r.args(dimensionIds)).delete().run(), - r.table('TemplateScale').getAll(r.args(scaleIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } - - try { - await r - .table('ReflectTemplate') - .replace((row) => row.without('type')) - .run() - } catch (e) { - console.log(e) - } - - try { - await r.table('MeetingSettings').filter({meetingType: 'poker'}).delete().run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200828161500-samlDomainAsId.ts b/packages/server/database/migrations/20200828161500-samlDomainAsId.ts deleted file mode 100644 index b66bd0f93ad..00000000000 --- a/packages/server/database/migrations/20200828161500-samlDomainAsId.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - const samlWithId = await r - .table('SAML') - .map((row) => { - return { - id: row('domain'), - domain: row('domain'), - url: row('url'), - metadata: row('metadata') - } - }) - .run() - - await r.table('SAML').insert(samlWithId, {conflict: 'replace'}).run() - - await r - .table('SAML') - .filter((row) => row('id').ne(row('domain'))) - .delete() - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - const samlWithoutId = await r - .table('SAML') - .map((row) => { - return { - domain: row('domain'), - url: row('url'), - metadata: row('metadata') - } - }) - .run() - - await r.table('SAML').insert(samlWithoutId).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200901212600-addCheckInMetrics.ts b/packages/server/database/migrations/20200901212600-addCheckInMetrics.ts deleted file mode 100644 index c4968136034..00000000000 --- a/packages/server/database/migrations/20200901212600-addCheckInMetrics.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const enum MeetingTypeEnum { - action = 'action', - retrospective = 'retrospective', - poker = 'poker' -} - -export const up = async function (r: R) { - try { - const getThreadIds = (row) => - r.args( - r - .table('AgendaItem') - .getAll(row('id'), {index: 'meetingId'}) - .map((row) => row('id')) - .coerceTo('array') as any - ) - await r - .table('NewMeeting') - .filter({meetingType: MeetingTypeEnum.action}) - .filter((row) => row('endedAt').default(null).ne(null)) - .update( - (row) => ({ - commentCount: r - .table('Comment') - .getAll(getThreadIds(row), {index: 'threadId'}) - .count() - .default(0), - agendaItemCount: r - .table('AgendaItem') - .getAll(row('id'), {index: 'meetingId'}) - .count() - .default(0) - }), - {nonAtomic: true} - ) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: MeetingTypeEnum.action}) - .replace((row) => row.without('commentCount', 'agendaItemCount')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200923163300-removeUserFields.ts b/packages/server/database/migrations/20200923163300-removeUserFields.ts deleted file mode 100644 index 2ea2c5474a7..00000000000 --- a/packages/server/database/migrations/20200923163300-removeUserFields.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - await r.table('User').replace(r.row.without('lastSeenAtURL', 'connectedSockets')).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('User').update({lastSeenAtURL: null, connectedSockets: []}).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200930085630-isStarter.ts b/packages/server/database/migrations/20200930085630-isStarter.ts deleted file mode 100644 index 82ccf1eecae..00000000000 --- a/packages/server/database/migrations/20200930085630-isStarter.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - const starters = [ - 'sailboatTemplate', - 'startStopContinueTemplate', - 'workingStuckTemplate', - 'fourLsTemplate', - 'gladSadMadTemplate' - ] - try { - await r.table('MeetingTemplate').getAll(r.args(starters)).update({isStarter: true}).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const starters = [ - 'sailboatTemplate', - 'startStopContinueTemplate', - 'workingStuckTemplate', - 'fourLsTemplate', - 'gladSadMadTemplate' - ] - try { - await r - .table('MeetingTemplate') - .getAll(r.args(starters)) - .replace((row) => row.without('isStarter')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20200930135100-addMoreRetroTemplates.ts b/packages/server/database/migrations/20200930135100-addMoreRetroTemplates.ts deleted file mode 100644 index e623aeb8553..00000000000 --- a/packages/server/database/migrations/20200930135100-addMoreRetroTemplates.ts +++ /dev/null @@ -1,271 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const createdAt = new Date() - -const templates = [ - { - createdAt: createdAt, - id: 'threeLittlePigsTemplate', - isActive: true, - name: 'Three Little Pigs 🐷 🐷 🐷', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true - }, - { - createdAt: createdAt, - id: 'energyLevelsTemplate', - isActive: true, - name: 'Energy Levels 🔋', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true - }, - { - createdAt: createdAt, - id: 'mountainClimberTemplate', - isActive: true, - name: 'Mountain Climber ⛰️', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true - }, - { - createdAt: createdAt, - id: 'winningStreakTemplate', - isActive: true, - name: 'Winning Streak 🏆', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true - } -] - -const reflectPrompts = [ - // Three Little Pigs: - { - createdAt: createdAt, - description: 'What is at risk of breaking?', - groupColor: '#52CC52', - id: 'promptHouseOfStraw', - isActive: true, - parentPromptId: 'promptWhatAdopt', - question: 'House of Straw', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'threeLittlePigsTemplate', - title: 'Start', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What needs more work?', - groupColor: '#E55C5C', - id: 'promptHouseOfSticks', - isActive: true, - parentPromptId: 'promptWhatCease', - question: 'House of Sticks', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'threeLittlePigsTemplate', - title: 'Stop', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What is rock solid and working well?', - groupColor: '#D9D916', - id: 'promptHouseOfBricks', - isActive: true, - parentPromptId: 'promptWhatKeep', - question: 'House of Bricks', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'threeLittlePigsTemplate', - title: 'Continue', - updatedAt: createdAt - }, - // Energy Levels: - { - createdAt: createdAt, - description: "What's your energy level going into the next Sprint?", - groupColor: '#7373E5', - id: 'promptSprintEnergy', - isActive: true, - question: 'Sprint Energy', - sortOrder: 3.9999999999999996, - teamId: 'aGhostTeam', - templateId: 'energyLevelsTemplate', - title: 'New prompt #3', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What depleted you?', - groupColor: '#E55C5C', - id: 'promptLowBattery', - isActive: true, - question: 'Low Battery', - sortOrder: 3.0000000000000004, - teamId: 'aGhostTeam', - templateId: 'energyLevelsTemplate', - title: 'New prompt #2', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What energized you?', - groupColor: '#52CC52', - id: 'promptFullyCharged', - isActive: true, - question: 'Fully Charged', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'energyLevelsTemplate', - title: 'New prompt', - updatedAt: createdAt - }, - // Mountain Climber: - { - createdAt: createdAt, - description: 'How did we feel about our work?', - groupColor: '#5CA0E5', - id: 'promptWeather', - isActive: true, - question: 'Weather 🌡️', - sortOrder: 2.0000000000000004, - teamId: 'aGhostTeam', - templateId: 'mountainClimberTemplate', - title: 'New prompt #3', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What more do we need to reach our goals?', - groupColor: '#E55C5C', - id: 'promptFirstAid', - isActive: true, - question: 'First Aid ⛑️', - sortOrder: 3, - teamId: 'aGhostTeam', - templateId: 'mountainClimberTemplate', - title: 'New prompt #4', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What helped us reach our goal?', - groupColor: '#52CC52', - id: 'promptRopes', - isActive: true, - question: 'Ropes 🧗', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'mountainClimberTemplate', - title: 'New prompt', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What stood in our way?', - groupColor: '#AC73E5', - id: 'promptBoulders', - isActive: true, - question: 'Boulders ⛰️', - sortOrder: 0.9999999999999998, - teamId: 'aGhostTeam', - templateId: 'mountainClimberTemplate', - title: 'New prompt #2', - updatedAt: createdAt - }, - // Winning Streak: - { - createdAt: createdAt, - description: 'What teamwork practices helped us reach our goals?', - groupColor: '#AC73E5', - id: 'promptTeamwork', - isActive: true, - question: 'Teamwork', - sortOrder: 1.0000000000000004, - teamId: 'aGhostTeam', - templateId: 'winningStreakTemplate', - title: 'New prompt #2', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'Share the love! Give a shoutout to someone who did great work!', - groupColor: '#45E5E5', - id: 'promptKudos', - isActive: true, - question: 'Kudos', - sortOrder: 2.9999999999999996, - teamId: 'aGhostTeam', - templateId: 'winningStreakTemplate', - title: 'New prompt #4', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'How can we maintain/replicate our success in future?', - groupColor: '#E55CA0', - id: 'promptRepeatingOurSuccess', - isActive: true, - question: 'Repeating our success', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'winningStreakTemplate', - title: 'New prompt #3', - updatedAt: createdAt - }, - { - createdAt: createdAt, - description: 'What are we proud of achieving?', - groupColor: '#52CC52', - id: 'promptBigWins', - isActive: true, - question: 'Big wins', - sortOrder: 0, - teamId: 'aGhostTeam', - templateId: 'winningStreakTemplate', - title: 'New prompt', - updatedAt: createdAt - } -] - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20201005090700-removedAtPrompts.ts b/packages/server/database/migrations/20201005090700-removedAtPrompts.ts deleted file mode 100644 index 999c14ec1ec..00000000000 --- a/packages/server/database/migrations/20201005090700-removedAtPrompts.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - const now = new Date() - try { - await r - .table('ReflectPrompt') - .update((row) => ({removedAt: r.branch(row('isActive').eq(true), null, now)})) - .run() - - await r.table('ReflectPrompt').replace(r.row.without('isActive')).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('ReflectPrompt') - .update((row) => ({isActive: r.branch(row('removedAt').eq(null), true, false)})) - .run() - - await r.table('ReflectPrompt').replace(r.row.without('removedAt')).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20201008134420-addPlainTextContentToTask.ts b/packages/server/database/migrations/20201008134420-addPlainTextContentToTask.ts deleted file mode 100644 index 2e9fe98bdbe..00000000000 --- a/packages/server/database/migrations/20201008134420-addPlainTextContentToTask.ts +++ /dev/null @@ -1,68 +0,0 @@ -import extractTextFromDraftString from 'parabol-client/utils/draftjs/extractTextFromDraftString' -import {R} from 'rethinkdb-ts' -import Task from '../types/Task' - -export const up = async function (r: R) { - const updateBatch = async (tasks: Task[]) => { - const updates = [] as { - taskId: string - plaintextContent: string - }[] - for (const task of tasks) { - updates.push({ - taskId: task.id, - plaintextContent: extractTextFromDraftString(task.content) - }) - } - return await r(updates) - .forEach((updateObj) => { - return r - .table('Task') - .get(updateObj('taskId')) - .update( - { - plaintextContent: updateObj('plaintextContent') - }, - { - returnChanges: true - } - ) - })('changes') - .run() - } - - try { - let i = 0 - const batchSize = 10000 - while (true) { - const tasks = await r - .table('Task') - .orderBy('id', {index: 'id'}) - .skip(batchSize * i) - .limit(batchSize) - .run() - if (!tasks?.length) break - await updateBatch(tasks) - i++ - } - /* process any new tasks that may have come in during first iteration */ - const missedTasks = await r - .table('Task') - .filter((row) => row.hasFields('plaintextContent').not()) - .run() - if (missedTasks.length) updateBatch(missedTasks) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('Task') - .replace((row) => row.without('plaintextContent')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20201014110000-templateScale.ts b/packages/server/database/migrations/20201014110000-templateScale.ts deleted file mode 100644 index da4ad1a69bc..00000000000 --- a/packages/server/database/migrations/20201014110000-templateScale.ts +++ /dev/null @@ -1,255 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const oldDataDate = new Date('2020-08-24') -const newDataDate = new Date() - -const oldScales = [ - { - id: 'fibonacciScale', - createdAt: oldDataDate, - updatedAt: oldDataDate, - name: 'Fibonacci', - values: ['1', '2', '3', '5', '8', '13', '21', '34'], - teamId: 'aGhostTeam' - }, - { - id: 'tshirtSizeScale', - createdAt: oldDataDate, - updatedAt: oldDataDate, - name: 'T-Shirt Sizes', - values: ['XS', 'SM', 'M', 'L', 'XL'], - teamId: 'aGhostTeam' - }, - { - id: 'fiveFingersScale', - createdAt: oldDataDate, - updatedAt: oldDataDate, - name: 'Five Fingers', - values: ['1', '2', '3', '4', '5'], - teamId: 'aGhostTeam' - } -] - -const oldDimensions = [ - { - createdAt: oldDataDate, - id: 'wsjfStoryPointsDimension', - name: 'Story Points', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'wsjfTemplate', - updatedAt: oldDataDate - }, - { - createdAt: oldDataDate, - id: 'eeStoryPointsDimension', - name: 'Story Points', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - updatedAt: oldDataDate - }, - { - createdAt: oldDataDate, - id: 'wsjfStoryValueDimension', - name: 'Story Value', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'wsjfTemplate', - updatedAt: oldDataDate - } -] - -const oldPokerTemplates = [ - { - createdAt: oldDataDate, - id: 'estimatedEffortTemplate', - isActive: true, - name: 'Estimated Effort', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - updatedAt: newDataDate - }, - { - createdAt: oldDataDate, - id: 'wsjfTemplate', - isActive: true, - name: 'Weighted Shortest Job First', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - updatedAt: oldDataDate - } -] - -const MAX_32_BIT_INTEGER = Math.pow(2, 31) - 1 -const newScales = [ - { - id: 'fibonacciScale', - createdAt: newDataDate, - updatedAt: newDataDate, - name: 'Fibonacci', - isStarter: true, - sortOrder: 0, - values: [ - {color: '#E55CA0', label: '?', value: -1, isSpecial: true}, - {color: '#5CA0E5', label: '1', value: 1}, - {color: '#5CA0E5', label: '2', value: 2}, - {color: '#45E595', label: '3', value: 3}, - {color: '#45E595', label: '5', value: 5}, - {color: '#45E595', label: '8', value: 8}, - {color: '#E59545', label: '13', value: 13}, - {color: '#E59545', label: '21', value: 21}, - {color: '#E59545', label: '34', value: 34}, - {color: '#AC72E5', label: 'X', value: MAX_32_BIT_INTEGER, isSpecial: true} - ], - teamId: 'aGhostTeam' - }, - { - id: 'tshirtSizeScale', - createdAt: newDataDate, - updatedAt: newDataDate, - name: 'T-Shirt Sizes', - isStarter: true, - sortOrder: 1, - values: [ - {color: '#E55CA0', label: '?', value: -1, isSpecial: true}, - {color: '#5CA0E5', label: 'XS', value: 1}, - {color: '#5CA0E5', label: 'SM', value: 2}, - {color: '#45E595', label: 'M', value: 3}, - {color: '#E59545', label: 'L', value: 4}, - {color: '#E59545', label: 'XL', value: 5}, - {color: '#AC72E5', label: 'X', value: MAX_32_BIT_INTEGER, isSpecial: true} - ], - teamId: 'aGhostTeam' - }, - { - id: 'fiveFingersScale', - createdAt: newDataDate, - updatedAt: newDataDate, - name: 'Five Fingers', - isStarter: true, - sortOrder: 2, - values: [ - {color: '#E55CA0', label: '?', value: -1, isSpecial: true}, - {color: '#5CA0E5', label: '1', value: 1}, - {color: '#5CA0E5', label: '2', value: 2}, - {color: '#45E595', label: '3', value: 3}, - {color: '#E59545', label: '4', value: 4}, - {color: '#E59545', label: '5', value: 5}, - {color: '#AC72E5', label: 'X', value: MAX_32_BIT_INTEGER, isSpecial: true} - ], - teamId: 'aGhostTeam' - } -] - -const newDimensions = [ - { - createdAt: newDataDate, - updatedAt: newDataDate, - id: 'eeStoryPointsDimension', - name: 'Story Points', - scaleId: 'tshirtSizeScale', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - sortOrder: 0 - }, - { - createdAt: newDataDate, - updatedAt: newDataDate, - id: 'eeStoryValueDimension', - name: 'Story Value', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - sortOrder: 1 - } -] - -const newPokerTemplates = [ - { - createdAt: newDataDate, - id: 'estimatedEffortTemplate', - isActive: true, - isStarter: true, - name: 'Estimated Effort & Value', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'poker', - updatedAt: newDataDate - } -] - -export const up = async function (r: R) { - try { - // create index 'teamId' for table TemplateScale - await r.table('TemplateScale').indexCreate('teamId').run() - - // clear TemplateScale table - await r.table('TemplateScale').delete().run() - - // insert new data to TemplateScale table - await r.table('TemplateScale').insert(newScales).run() - - // create index 'teamId' for TemplateDimension table - await r.table('TemplateDimension').indexCreate('teamId').run() - - // clear TemplateDimension table - await r.table('TemplateDimension').delete().run() - - // insert new data to TemplateDimension table - await r.table('TemplateDimension').insert(newDimensions).run() - - // clear poker template data in MeetingTemplate table - await r - .table('MeetingTemplate') - .filter((template) => - r.expr(['estimatedEffortTemplate', 'wsjfTemplate']).contains(template('id')) - ) - .delete() - .run() - - // insert new poker template data to MeetingTemplate table - await r.table('MeetingTemplate').insert(newPokerTemplates).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - // drop index 'teamId' for table TemplateScale - await r.table('TemplateScale').indexDrop('teamId').run() - - // clear TemplateScale table - await r.table('TemplateScale').delete().run() - - // insert old data to TemplateScale table - await r.table('TemplateScale').insert(oldScales).run() - - // drop index 'teamId' for TemplateDimension table - await r.table('TemplateDimension').indexDrop('teamId').run() - - // clear TemplateDimension table - await r.table('TemplateDimension').delete().run() - - // insert old data to TemplateDimension table - await r.table('TemplateDimension').insert(oldDimensions).run() - - // clear poker template data in MeetingTemplate table - await r - .table('MeetingTemplate') - .filter((template) => - r.expr(['estimatedEffortTemplate', 'wsjfTemplate']).contains(template('id')) - ) - .delete() - .run() - - // insert old poker template data to MeetingTemplate table - await r.table('MeetingTemplate').insert(oldPokerTemplates).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20201116132414-modifyDefaultPokerTemplate.ts b/packages/server/database/migrations/20201116132414-modifyDefaultPokerTemplate.ts deleted file mode 100644 index 67768a6102a..00000000000 --- a/packages/server/database/migrations/20201116132414-modifyDefaultPokerTemplate.ts +++ /dev/null @@ -1,152 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const oldDataDate = new Date('2020-11-04') -const newDataDate = new Date() - -const currentDimensions = [ - { - createdAt: oldDataDate, - updatedAt: oldDataDate, - id: 'eeStoryPointsDimension', - name: 'Story Points', - scaleId: 'tshirtSizeScale', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - sortOrder: 0 - }, - { - createdAt: oldDataDate, - updatedAt: oldDataDate, - id: 'eeStoryValueDimension', - name: 'Story Value', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - sortOrder: 1 - } -] - -const currentPokerTemplates = [ - { - createdAt: oldDataDate, - id: 'estimatedEffortTemplate', - isActive: true, - isStarter: true, - name: 'Estimated Effort & Value', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'poker', - updatedAt: oldDataDate - } -] - -const newDimensions = [ - { - createdAt: newDataDate, - id: 'wsjfStoryPointsDimension', - name: 'Story Points', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'wsjfTemplate', - updatedAt: newDataDate, - sortOrder: 0 - }, - { - createdAt: newDataDate, - id: 'eeStoryPointsDimension', - name: 'Story Points', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'estimatedEffortTemplate', - updatedAt: newDataDate, - sortOrder: 0 - }, - { - createdAt: newDataDate, - id: 'wsjfStoryValueDimension', - name: 'Story Value', - scaleId: 'fibonacciScale', - teamId: 'aGhostTeam', - templateId: 'wsjfTemplate', - updatedAt: newDataDate, - sortOrder: 1 - } -] - -const newPokerTemplates = [ - { - createdAt: newDataDate, - id: 'estimatedEffortTemplate', - isActive: true, - isStarter: true, - name: 'Estimated Effort', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'poker', - updatedAt: newDataDate - }, - { - createdAt: newDataDate, - id: 'wsjfTemplate', - isActive: true, - isStarter: true, - name: 'Weighted Shortest Job First', - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'poker', - updatedAt: newDataDate - } -] - -export const up = async function (r: R) { - try { - // Delete old template - await r.table('MeetingTemplate').get('estimatedEffortTemplate').delete().run() - - // Delete old dimensions - await r - .table('TemplateDimension') - .getAll(r.args(['eeStoryPointsDimension', 'eeStoryValueDimension'])) - .delete() - .run() - - // Insert new dimensions - await r.table('TemplateDimension').insert(newDimensions).run() - - // Insert new templates - await r.table('MeetingTemplate').insert(newPokerTemplates).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - // Delete new template - await r - .table('MeetingTemplate') - .getAll(r.args(['estimatedEffortTemplate', 'wsjfTemplate'])) - .delete() - .run() - - // Delete new dimensions - await r - .table('TemplateDimension') - .getAll( - r.args(['eeStoryPointsDimension', 'wsjfStoryValueDimension', 'wsjfStoryPointsDimension']) - ) - .delete() - .run() - - // Insert old dimensions - await r.table('TemplateDimension').insert(currentDimensions).run() - - // Insert old templates - await r.table('MeetingTemplate').insert(currentPokerTemplates).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20201118132835-removeValueFieldInScaleValue.ts b/packages/server/database/migrations/20201118132835-removeValueFieldInScaleValue.ts deleted file mode 100644 index 9290f7927dd..00000000000 --- a/packages/server/database/migrations/20201118132835-removeValueFieldInScaleValue.ts +++ /dev/null @@ -1,149 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const oldDataDate = new Date('2020-11-04') -const newDataDate = new Date() -const MAX_32_BIT_INTEGER = Math.pow(2, 31) - 1 -const oldScales = [ - { - id: 'fibonacciScale', - createdAt: oldDataDate, - updatedAt: oldDataDate, - name: 'Fibonacci', - isStarter: true, - sortOrder: 0, - values: [ - {color: '#E55CA0', label: '?', value: -1, isSpecial: true}, - {color: '#5CA0E5', label: '1', value: 1}, - {color: '#5CA0E5', label: '2', value: 2}, - {color: '#45E595', label: '3', value: 3}, - {color: '#45E595', label: '5', value: 5}, - {color: '#45E595', label: '8', value: 8}, - {color: '#E59545', label: '13', value: 13}, - {color: '#E59545', label: '21', value: 21}, - {color: '#E59545', label: '34', value: 34}, - {color: '#AC72E5', label: 'X', value: MAX_32_BIT_INTEGER, isSpecial: true} - ], - teamId: 'aGhostTeam' - }, - { - id: 'tshirtSizeScale', - createdAt: oldDataDate, - updatedAt: oldDataDate, - name: 'T-Shirt Sizes', - isStarter: true, - sortOrder: 1, - values: [ - {color: '#E55CA0', label: '?', value: -1, isSpecial: true}, - {color: '#5CA0E5', label: 'XS', value: 1}, - {color: '#5CA0E5', label: 'SM', value: 2}, - {color: '#45E595', label: 'M', value: 3}, - {color: '#E59545', label: 'L', value: 4}, - {color: '#E59545', label: 'XL', value: 5}, - {color: '#AC72E5', label: 'X', value: MAX_32_BIT_INTEGER, isSpecial: true} - ], - teamId: 'aGhostTeam' - }, - { - id: 'fiveFingersScale', - createdAt: oldDataDate, - updatedAt: oldDataDate, - name: 'Five Fingers', - isStarter: true, - sortOrder: 2, - values: [ - {color: '#E55CA0', label: '?', value: -1, isSpecial: true}, - {color: '#5CA0E5', label: '1', value: 1}, - {color: '#5CA0E5', label: '2', value: 2}, - {color: '#45E595', label: '3', value: 3}, - {color: '#E59545', label: '4', value: 4}, - {color: '#E59545', label: '5', value: 5}, - {color: '#AC72E5', label: 'X', value: MAX_32_BIT_INTEGER, isSpecial: true} - ], - teamId: 'aGhostTeam' - } -] - -const newScales = [ - { - id: 'fibonacciScale', - createdAt: newDataDate, - updatedAt: newDataDate, - name: 'Fibonacci', - isStarter: true, - sortOrder: 0, - values: [ - {color: '#5CA0E5', label: '1'}, - {color: '#5CA0E5', label: '2'}, - {color: '#45E595', label: '3'}, - {color: '#45E595', label: '5'}, - {color: '#45E595', label: '8'}, - {color: '#E59545', label: '13'}, - {color: '#E59545', label: '21'}, - {color: '#E59545', label: '34'}, - {color: '#E55CA0', label: '?', isSpecial: true}, - {color: '#AC72E5', label: 'Pass', isSpecial: true} - ], - teamId: 'aGhostTeam' - }, - { - id: 'tshirtSizeScale', - createdAt: newDataDate, - updatedAt: newDataDate, - name: 'T-Shirt Sizes', - isStarter: true, - sortOrder: 1, - values: [ - {color: '#5CA0E5', label: 'XS'}, - {color: '#5CA0E5', label: 'SM'}, - {color: '#45E595', label: 'M'}, - {color: '#E59545', label: 'L'}, - {color: '#E59545', label: 'XL'}, - {color: '#E55CA0', label: '?', isSpecial: true}, - {color: '#AC72E5', label: 'Pass', isSpecial: true} - ], - teamId: 'aGhostTeam' - }, - { - id: 'fiveFingersScale', - createdAt: newDataDate, - updatedAt: newDataDate, - name: 'Five Fingers', - isStarter: true, - sortOrder: 2, - values: [ - {color: '#5CA0E5', label: '1'}, - {color: '#5CA0E5', label: '2'}, - {color: '#45E595', label: '3'}, - {color: '#E59545', label: '4'}, - {color: '#E59545', label: '5'}, - {color: '#E55CA0', label: '?', isSpecial: true}, - {color: '#AC72E5', label: 'Pass', isSpecial: true} - ], - teamId: 'aGhostTeam' - } -] - -export const up = async function (r: R) { - try { - // clear TemplateScale table - await r.table('TemplateScale').delete().run() - - // insert new data to TemplateScale table - await r.table('TemplateScale').insert(newScales).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const MAX_32_BIT_INTEGER = Math.pow(2, 31) - 1 - try { - // clear TemplateScale table - await r.table('TemplateScale').delete().run() - - // insert old data to TemplateScale table - await r.table('TemplateScale').insert(oldScales).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20201214104322-noPokerSpecial.ts b/packages/server/database/migrations/20201214104322-noPokerSpecial.ts deleted file mode 100644 index 6296f30b6d1..00000000000 --- a/packages/server/database/migrations/20201214104322-noPokerSpecial.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - await r - .table('TemplateScale') - .update((row) => ({ - values: row('values').map((scaleValue) => scaleValue.without('isSpecial')) - })) - .run() - } catch (e) { - // noop - } -} - -export const down = async function (r: R) { - const specials = ['?', 'Pass'] - try { - await r - .table('TemplateScale') - .update((row) => ({ - values: row('values').map((scaleValue) => { - return r.branch( - r(specials).contains(scaleValue('label')), - scaleValue.merge({ - isSpecial: true - }), - scaleValue - ) - }) - })) - .run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20201222114114-samlDomains.ts b/packages/server/database/migrations/20201222114114-samlDomains.ts deleted file mode 100644 index 66f4821a952..00000000000 --- a/packages/server/database/migrations/20201222114114-samlDomains.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('SAML').indexCreate('domains', {multi: true}).run(), - r.table('SAML').indexDrop('domain') - ]) - } catch (e) { - // noop - } - try { - await r - .table('SAML') - .replace((row) => row.merge({domains: [row('domain').add('.com')]}).without('domain', 'cert')) - .run() - } catch (e) { - // noop - } -} - -export const down = async function (r: R) { - try { - await Promise.all([ - r.table('SAML').indexCreate('domain').run(), - r.table('SAML').indexDrop('domains') - ]) - } catch (e) { - // noop - } - try { - await r - .table('SAML') - .replace((row) => - row.merge({domain: row('domain').nth(0).split('.').nth(0)}).without('domains') - ) - .run() - } catch (e) { - // noop - } -} diff --git a/packages/server/database/migrations/20201223205050-removeEmptyTemplates.ts b/packages/server/database/migrations/20201223205050-removeEmptyTemplates.ts deleted file mode 100644 index 1927f76a50f..00000000000 --- a/packages/server/database/migrations/20201223205050-removeEmptyTemplates.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - const now = new Date() - try { - const promptlessTemplateIds = await r - .table('MeetingTemplate') - .filter({type: 'retrospective'}) - .merge((template) => ({ - promptCount: r - .table('ReflectPrompt') - .getAll(template('id'), {index: 'templateId'}) - .filter((row) => row('removedAt').default(null).eq(null)) - .count() - .default(0) - })) - .filter((template) => template('promptCount').eq(0)) - .map((row) => row('id')) - .coerceTo('array') - .run() - - await r - .table('MeetingTemplate') - .getAll(r.args(promptlessTemplateIds)) - .filter({isActive: true}) - .update({isActive: false}) - .run() - - await r - .table('NewMeeting') - .getAll(r.args(promptlessTemplateIds), {index: 'templateId'}) - .filter((meeting) => meeting.hasFields('endedAt').not()) - .update({endedAt: now, removedAt: now}) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - // noop -} diff --git a/packages/server/database/migrations/20210301164434-renameFocusedPhaseItemIdToFocusedPromptId.ts b/packages/server/database/migrations/20210301164434-renameFocusedPhaseItemIdToFocusedPromptId.ts deleted file mode 100644 index e31eb786efa..00000000000 --- a/packages/server/database/migrations/20210301164434-renameFocusedPhaseItemIdToFocusedPromptId.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .update({ - phases: r.row('phases').map((phase) => { - return r.branch( - phase('focusedPhaseItemId').default(null).ne(null), - phase - .without('focusedPhaseItemId') - .merge({focusedPromptId: phase('focusedPhaseItemId')}), - phase - ) - }) - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .update({ - phases: r.row('phases').map((phase) => { - return r.branch( - phase('focusedPromptId').default(null).ne(null), - phase.without('focusedPromptId').merge({focusedPhaseItemId: phase('focusedPromptId')}), - phase - ) - }) - }) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210324160018-mergeDuplicateUsers.ts b/packages/server/database/migrations/20210324160018-mergeDuplicateUsers.ts deleted file mode 100644 index 452b5b45fa3..00000000000 --- a/packages/server/database/migrations/20210324160018-mergeDuplicateUsers.ts +++ /dev/null @@ -1,168 +0,0 @@ -import {R} from 'rethinkdb-ts' -import User from '../types/User' - -export const up = async function (r: R) { - // fix the first user (duplicated later) having a string for `tms` field - await r - .table('User') - .getAll('love@parabol.co', {index: 'email'}) - .orderBy('createdAt') - .limit(1) - .update((row) => ({tms: [row('tms')]})) - .run() - - const updateTeamMember = async (goodUserId: string, badUserId: string) => { - // we don't want to delete the team member because the NewMeeting object - // references it in the TeamMemberStages (checkin & update stages) - // instead, we just inactivate - const {goodTeamMembers, badTeamMembers} = await r({ - goodTeamMembers: r - .table('TeamMember') - .getAll(goodUserId, {index: 'userId'}) - .coerceTo('array') as any, - badTeamMembers: r - .table('TeamMember') - .getAll(badUserId, {index: 'userId'}) - .update( - { - userId: goodUserId, - isNotRemoved: false - }, - {returnChanges: true} - )('changes')('new_val') - .default([]) as any - }).run() - - // for each bad team member, see if a good one exists on that team - // if the good one does not exist, then create it since the old in now inactive - const teamMembersToInsert = [] as any[] - badTeamMembers.forEach((badTeamMember) => { - const goodTeamMember = goodTeamMembers.find( - (teamMember) => teamMember.id === badTeamMember.id - ) - if (!goodTeamMember) { - badTeamMember.id = `${goodUserId}::${badTeamMember.teamId}` - teamMembersToInsert.push(badTeamMember) - } - }) - await r.table('TeamMember').insert(badTeamMembers).run() - // update org user - // it's possible 2 user objects could exist on the same, that's OK for now - await r - .table('OrganizationUser') - .getAll(badUserId, {index: 'userId'}) - .update({ - userId: goodUserId - }) - .run() - - // replace meeting members with updated ones - const meetingMembers = await r.table('MeetingMember').getAll(badUserId, {index: 'userId'}).run() - const updatedMeetingMembers = meetingMembers.map((meetingMember) => ({ - ...meetingMember, - id: `${goodUserId}::${meetingMember.meetingId}`, - userId: goodUserId - })) - await r.table('MeetingMember').getAll(badUserId, {index: 'userId'}).delete().run() - await r.table('MeetingMember').insert(updatedMeetingMembers).run() - - // replace team invitations - await r - .table('TeamInvitation') - .filter({invitedBy: badUserId}) - .update({invitedBy: goodUserId}) - .run() - await r - .table('Notification') - .filter({ - evictorUserId: badUserId - }) - .update({ - evictorUserId: goodUserId - }) - .run() - await r - .table('Notification') - .filter({ - archivorUserId: badUserId - }) - .update({ - archivorUserId: goodUserId - }) - .run() - } - - try { - /*const affectedEmails = (await r - .table('User') - .group('email') - .count() - .ungroup() - .filter((row) => row('reduction').gt(1))('group') - .filter((row) => row.ne('DELETED')) - .run({arrayLimit: 200000})) as string[]*/ - - // put emails in db to keep PII secret - const affectedEmails = await r - .table('DuplicateEmails') - .getField('email') - .coerceTo('array') - .run() - - const allDuplicates = [] as Promise[] - affectedEmails.forEach((email) => { - allDuplicates.push( - r.table('User').getAll(email, {index: 'email'}).orderBy('createdAt').coerceTo('array').run() - ) - }) - - const toUpdate = [] as User[] - const toDeleteIds = [] as string[] - const teamMemberUpdates = [] as Promise[] - for await (const innerArr of allDuplicates) { - const [old, ...newer] = innerArr - const {identities: oldIdentities} = old - for (const dup of newer) { - const {identities} = dup - for (const identity of identities) { - const {type} = identity - const matchingOldIdentityIdx = oldIdentities.findIndex( - (identity) => identity.type === type - ) - if (matchingOldIdentityIdx !== -1) { - oldIdentities[matchingOldIdentityIdx] = identity - } - } - old.tms = old.tms.concat(dup.tms) - old.email = dup.email ? dup.email : old.email - old.picture = dup.picture ? dup.picture : old.picture - toDeleteIds.push(dup.id) - teamMemberUpdates.push(updateTeamMember(old.id, dup.id)) - } - old.tms = Array.from(new Set(old.tms)) - toUpdate.push(old) - } - - await r(toUpdate) - .forEach((update) => { - return r - .table('User') - .get(update('id')) - .update({ - email: update('email'), - picture: update('picture'), - tms: update('tms'), - identities: update('identities') - }) - }) - .run() - - await r.table('User').getAll(r.args(toDeleteIds)).delete().run() - } catch (e) { - // console.log(e) - } -} - -export const down = async () => { - // noop -} diff --git a/packages/server/database/migrations/20210324160029-prepareBackfillUsers.ts b/packages/server/database/migrations/20210324160029-prepareBackfillUsers.ts deleted file mode 100644 index b3ff30ef31e..00000000000 --- a/packages/server/database/migrations/20210324160029-prepareBackfillUsers.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const up = async function (r) { - try { - await r.table('User').indexCreate('updatedAt').run() - await r.table('User').indexWait().run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await r.table('User').indexDrop('updatedAt').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210324160039-prepareBackfillTeams.ts b/packages/server/database/migrations/20210324160039-prepareBackfillTeams.ts deleted file mode 100644 index 30cefbbec55..00000000000 --- a/packages/server/database/migrations/20210324160039-prepareBackfillTeams.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const up = async function (r) { - try { - // ensure createdAt field - await r - .table('Team') - .filter((row) => row.hasFields('createdAt').not()) - .update({createdAt: new Date()}) - .run() - // ensure updatedAt field - await r - .table('Team') - .filter((row) => row.hasFields('updatedAt').not()) - .update({updatedAt: r.row('createdAt')}) - .run() - await r.table('Team').indexCreate('updatedAt').run() - await r.table('Team').indexWait().run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await r.table('Team').indexDrop('updatedAt').run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210324160118-swapTatorIdWithCreatedBy.ts b/packages/server/database/migrations/20210324160118-swapTatorIdWithCreatedBy.ts deleted file mode 100644 index 0ae5abf75f7..00000000000 --- a/packages/server/database/migrations/20210324160118-swapTatorIdWithCreatedBy.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - await r - .table('NewMeeting') - .replace((row) => - row - .merge({ - createdBy: row('defaultFacilitatorUserId') - }) - .without('defaultFacilitatorUserId') - ) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - await r - .table('NewMeeting') - .replace((row) => - row - .merge({ - defaultFacilitatorUserId: row('createdBy') - }) - .without('createdBy') - ) - .run() -} diff --git a/packages/server/database/migrations/20210324160125-pokerSpectate.ts b/packages/server/database/migrations/20210324160125-pokerSpectate.ts deleted file mode 100644 index 8bb6bff0093..00000000000 --- a/packages/server/database/migrations/20210324160125-pokerSpectate.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const up = async function (r) { - try { - await r({ - teamMembers: r.table('TeamMember').update({isSpectatingPoker: false}), - meetingMembers: r - .table('MeetingMember') - .filter({meetingType: 'poker'}) - .update({isSpectating: false}) - }).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await r({ - teamMembers: r.table('TeamMember').replace((row) => row.without('isSpectatingPoker')), - meetingMembers: r - .table('MeetingMember') - .filter({meetingType: 'poker'}) - .replace((row) => row.without('isSpectating')) - }).run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210330163028-addPriorityScale.ts b/packages/server/database/migrations/20210330163028-addPriorityScale.ts deleted file mode 100644 index 2feb3bdb7ec..00000000000 --- a/packages/server/database/migrations/20210330163028-addPriorityScale.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {PALETTE} from 'parabol-client/styles/paletteV3' -import {PokerCards} from 'parabol-client/types/constEnums' -import {R} from 'rethinkdb-ts' - -const priorityScaleId = 'priorityScale' -const priorityScale = [ - { - id: priorityScaleId, - createdAt: new Date(), - updatedAt: new Date(), - name: 'Priorities', - isStarter: true, - sortOrder: 3, - values: [ - {color: PALETTE.FUSCIA_400, label: PokerCards.QUESTION_CARD}, - {color: PALETTE.SKY_500, label: 'P0'}, - {color: PALETTE.SKY_500, label: 'P1'}, - {color: PALETTE.JADE_400, label: 'P2'}, - {color: PALETTE.JADE_400, label: 'P3'}, - {color: PALETTE.TERRA_300, label: 'P4'}, - {color: PALETTE.TERRA_300, label: 'P5'}, - {color: PALETTE.GRAPE_500, label: PokerCards.PASS_CARD} - ], - teamId: 'aGhostTeam' - } -] - -export const up = async function (r: R) { - try { - await r.table('TemplateScale').insert(priorityScale).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r.table('TemplateScale').get(priorityScaleId).delete().run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210425123805-enforceCharLimitOnUserAndTeam.ts b/packages/server/database/migrations/20210425123805-enforceCharLimitOnUserAndTeam.ts deleted file mode 100644 index cf2f1ff9adc..00000000000 --- a/packages/server/database/migrations/20210425123805-enforceCharLimitOnUserAndTeam.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - TEAM_NAME_LIMIT, - USER_EMAIL_LIMIT, - USER_PREFERRED_NAME_LIMIT -} from '../../postgres/constants' - -const teamIdsWithTooLongNames = ['p_PZKkjmX', 'PQ8s3SUnt', 'yON8V5niok', 'yeV_e3hUw'] - -const userIdsWithTooLongNames = [ - 'local|nm0nwe77AA', - 'local|25_i0w4u', - 'local|1BIzNRvD', - 'local|1wzYF43N' -] - -const userIdsWithTooLongEmails = ['local|nm0nwe77AA', 'local|1BIzNRvD', 'local|1wzYF43N'] - -/* - Queries to get the ids: - - await r - .table('Team') - .merge({nameLen: r.row('name').count()}) - .filter(r.row('nameLen').gt(TEAM_NAME_LIMIT)) - .getField('id') - .coerceTo('array') - .run() - - await r - .table('User') - .merge({preferredNameLen: r.row('preferredName').count()}) - .filter(r.row('preferredNameLen').gt(USER_PREFERRED_NAME_LIMIT)) - .getField('id') - .coerceTo('array') - .run() - - await r - .table('User') - .merge({emailLen: r.row('email').count()}) - .filter(r.row('emailLen').gt(USER_EMAIL_LIMIT)) - .getField('id') - .coerceTo('array') - .run({arrayLimit: 300000}) -*/ - -export const up = async function (r) { - await Promise.all([ - r - .table('Team') - .getAll(r.args(teamIdsWithTooLongNames)) - .update({ - name: r.row('name').slice(0, TEAM_NAME_LIMIT) - }) - .run(), - r - .table('User') - .getAll(r.args(userIdsWithTooLongNames)) - .update({ - preferredName: r.row('preferredName').slice(0, USER_PREFERRED_NAME_LIMIT) - }) - .run(), - r - .table('User') - .getAll(r.args(userIdsWithTooLongEmails)) - .update({ - email: r.row('email').slice(0, USER_EMAIL_LIMIT) - }) - .run() - ]) -} - -export const down = function (r) { - // noop -} diff --git a/packages/server/database/migrations/20210602120505-addAdditionalRetroTemplates.ts b/packages/server/database/migrations/20210602120505-addAdditionalRetroTemplates.ts deleted file mode 100644 index 4d89e347f34..00000000000 --- a/packages/server/database/migrations/20210602120505-addAdditionalRetroTemplates.ts +++ /dev/null @@ -1,176 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const createdAt = new Date() - -const nameToId = (name: string, isTemplate: boolean) => { - const cleanedName = name - .replace(/[^0-9a-z-A-Z ]/g, '') // remove emojis and apostrophes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${isTemplate ? 'Template' : 'Prompt'}` -} - -const makeTemplate = (name: string) => ({ - createdAt, - id: nameToId(name, true), - isActive: true, - name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true -}) - -type PromptInfo = { - question: string - description: string - groupColor: string - templateId: string - sortOrder: number -} - -const makePrompt = (promptInfo: PromptInfo) => { - const {question, description, groupColor, templateId, sortOrder} = promptInfo - return { - createdAt, - description, - groupColor, - // FIXME this may create duplicated ids - id: nameToId(question, false), - isActive: true, - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - title: question, - updatedAt: createdAt - } -} - -const templateNames = [ - 'Drop Add Keep Improve (DAKI)', - 'Lean Coffee ☕', - 'Starfish ⭐', - 'What Went Well' -] - -const promptsInfo = [ - { - question: 'Drop', - description: 'What should we stop?', - groupColor: '#52CC52', - templateId: 'dropAddKeepImproveDAKITemplate', - sortOrder: 0 - }, - { - question: 'Add', - description: 'What should we try or adopt?', - groupColor: '#E55C5C', - templateId: 'dropAddKeepImproveDAKITemplate', - sortOrder: 1 - }, - { - question: 'Keep', - description: 'What should we continue doing?', - groupColor: '#D9D916', - templateId: 'dropAddKeepImproveDAKITemplate', - sortOrder: 2 - }, - { - question: 'Improve', - description: 'What should we improve or revise?', - groupColor: '#7373E5', - templateId: 'dropAddKeepImproveDAKITemplate', - sortOrder: 3 - }, - { - question: 'To Discuss', - description: `What should we talk about? We'll group related items into topics and vote on them to decide what to chat about`, - groupColor: '#45E5E5', - templateId: 'leanCoffeeTemplate', - sortOrder: 0 - }, - { - question: 'Keep Doing 🌀', - description: `What behaviors are working and adding value?`, - groupColor: '#7373E5', - templateId: 'starfishTemplate', - sortOrder: 0 - }, - { - question: 'Less of ➖', - description: `What are we overdoing or spending too much time on?`, - groupColor: '#D9D916', - templateId: 'starfishTemplate', - sortOrder: 1 - }, - { - question: 'More of ➕', - description: `What should we take advantage of or spend more time on?`, - groupColor: '#45E5E5', - templateId: 'starfishTemplate', - sortOrder: 2 - }, - { - question: 'Stop ⏹️', - description: `What isn't adding value or helping the team?`, - groupColor: '#E55C5C', - templateId: 'starfishTemplate', - sortOrder: 3 - }, - { - question: 'Start ⏯️', - description: `What new things should we explore or start doing?`, - groupColor: '#52CC52', - templateId: 'starfishTemplate', - sortOrder: 4 - }, - { - question: 'What went well 😄', - description: `What good things happened this sprint?`, - groupColor: '#7373E5', - templateId: 'whatWentWellTemplate', - sortOrder: 0 - }, - { - question: `What didn't go well 😞`, - description: `What didn't go as planned or desired this sprint?`, - groupColor: '#E55C5C', - templateId: 'whatWentWellTemplate', - sortOrder: 1 - } -] as const - -const templates = templateNames.map((templateName) => makeTemplate(templateName)) -const reflectPrompts = promptsInfo.map((promptInfo: PromptInfo) => makePrompt(promptInfo)) - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210624120419-addPokerStats.ts b/packages/server/database/migrations/20210624120419-addPokerStats.ts deleted file mode 100644 index fe712dc9536..00000000000 --- a/packages/server/database/migrations/20210624120419-addPokerStats.ts +++ /dev/null @@ -1,70 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const enum MeetingTypeEnum { - action = 'action', - retrospective = 'retrospective', - poker = 'poker' -} -const enum NewMeetingPhaseTypeEnum { - lobby = 'lobby', - checkin = 'checkin', - updates = 'updates', - firstcall = 'firstcall', - agendaitems = 'agendaitems', - lastcall = 'lastcall', - reflect = 'reflect', - group = 'group', - vote = 'vote', - discuss = 'discuss', - SUMMARY = 'SUMMARY', - SCOPE = 'SCOPE', - ESTIMATE = 'ESTIMATE' -} - -export const up = async function (r: R) { - try { - const getDiscussionIds = (meetingRow) => { - return meetingRow('phases') - .filter({phaseType: NewMeetingPhaseTypeEnum.ESTIMATE})('stages') - .concatMap((row) => row('discussionId')) - } - const getCompletedStories = (meetingRow) => { - return meetingRow('phases') - .filter({phaseType: NewMeetingPhaseTypeEnum.ESTIMATE})('stages') - .nth(0) - .filter({isComplete: true}) - .map((row) => row('serviceTaskId')) - } - - await r - .table('NewMeeting') - .filter({meetingType: MeetingTypeEnum.poker}) - .filter((row) => row('endedAt').default(null).ne(null)) - .update( - (row) => ({ - commentCount: r - .table('Comment') - .getAll(r.args(getDiscussionIds(row)), {index: 'discussionId'}) - .count() - .default(0), - storyCount: getCompletedStories(row).count().default(0) - }), - {nonAtomic: true} - ) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: MeetingTypeEnum.poker}) - .replace((row) => row.without('commentCount', 'storyCount')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210624121905-sortJiraDimensionFields.ts b/packages/server/database/migrations/20210624121905-sortJiraDimensionFields.ts deleted file mode 100644 index 1290a480227..00000000000 --- a/packages/server/database/migrations/20210624121905-sortJiraDimensionFields.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - // With JiraDimensionFieldMap migration, sorting this field is not necessary anymore - /* - await r - .table('Team') - .filter(r.row('jiraDimensionFields').default([]).count().gt(0)) - .update((team) => ({ - jiraDimensionFields: team('jiraDimensionFields') - .default([]) - .orderBy((jiraDimensionField) => jiraDimensionField.coerceTo('string')) - })) - */ -} - -export const down = async function (r: R) { - //noop -} diff --git a/packages/server/database/migrations/20210629164700-task-hash.ts b/packages/server/database/migrations/20210629164700-task-hash.ts deleted file mode 100644 index e2260819de0..00000000000 --- a/packages/server/database/migrations/20210629164700-task-hash.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - // add the hash - await r({ - jira: r - .table('Task') - .filter((task) => { - return task('integration')('service').eq('jira').default(false) - }) - .update((task) => ({ - integrationHash: r('jira:') - .add(task('integration')('cloudId')) - .add(':') - .add(task('integration')('issueKey')) - .default('BAD_HASH'), - integration: task('integration').merge({ - accessUserId: task('createdBy') - }) - })), - github: r - .table('Task') - .filter((task) => { - return task('integration')('service').eq('github').default(false) - }) - .update((task) => ({ - integrationHash: r('gh:') - .add(task('integration')('nameWithOwner')) - .add(':') - .add(task('integration')('issueNumber')) - .default('BAD_HASH'), - integration: task('integration').merge({ - accessUserId: task('createdBy') - }) - })) - }).run() - - // add index - await r.table('Task').indexCreate('integrationHash').run() -} - -export const down = async function (r: R) { - await r.table('Task').indexDrop('integrationHash').run() - await r - .table('Task') - .filter((task) => task('integrationHash').default(null).ne(null)) - .replace((row) => row.without('integrationHash')) - .run() -} diff --git a/packages/server/database/migrations/20210708185500-removePromptTitle.ts b/packages/server/database/migrations/20210708185500-removePromptTitle.ts deleted file mode 100644 index 89ec7ff9ef4..00000000000 --- a/packages/server/database/migrations/20210708185500-removePromptTitle.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {R} from 'rethinkdb-ts' -export const up = async function (r: R) { - try { - await r.table('ReflectPrompt').replace(r.row.without('title')).run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('ReflectPrompt') - .update((row) => ({title: row('question')})) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20210714160201-addIsWatched.ts b/packages/server/database/migrations/20210714160201-addIsWatched.ts deleted file mode 100644 index e4df11a86a9..00000000000 --- a/packages/server/database/migrations/20210714160201-addIsWatched.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r - .table('User') - .filter((row) => row.hasFields('isWatched').not()) - .update({isWatched: false}) - .run() -} - -export const down = async function (r: R) { - await r - .table('User') - .replace((row) => row.without('isWatched')) - .run() -} diff --git a/packages/server/database/migrations/20210719161718-deletedUserEmailBackfill.ts b/packages/server/database/migrations/20210719161718-deletedUserEmailBackfill.ts deleted file mode 100644 index 3cfa2a45a2b..00000000000 --- a/packages/server/database/migrations/20210719161718-deletedUserEmailBackfill.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r - .table('User') - .filter({isRemoved: true}) - .update((user) => ({ - email: r.expr('DELETED:').add(user('id').add(':1626360264029')) - })) - .run() -} - -export const down = async function (r: R) { - await r - .table('User') - .filter({isRemoved: true}) - .update({ - email: 'DELETED' - }) - .run() -} diff --git a/packages/server/database/migrations/20210721151034-integration-hash.ts b/packages/server/database/migrations/20210721151034-integration-hash.ts deleted file mode 100644 index 69d2e9bb5c6..00000000000 --- a/packages/server/database/migrations/20210721151034-integration-hash.ts +++ /dev/null @@ -1,56 +0,0 @@ -import {R} from 'rethinkdb-ts' - -// note this is almost identical to task-hash (just a different integrationhash prefix) but the old migration didn't run in prod -// due to a merge conflict on migration timestamps -export const up = async function (r: R) { - // add the hash - try { - await r({ - jira: r - .table('Task') - .filter((task) => { - return task('integration')('service').eq('jira').default(false) - }) - .update((task) => ({ - integrationHash: task('integration')('cloudId') - .add(':') - .add(task('integration')('issueKey')) - .default('BAD_HASH'), - integration: task('integration').merge({ - accessUserId: task('createdBy') - }) - })), - github: r - .table('Task') - .filter((task) => { - return task('integration')('service').eq('github').default(false) - }) - .update((task) => ({ - integrationHash: task('integration')('nameWithOwner') - .add(':') - .add(task('integration')('issueNumber')) - .default('BAD_HASH'), - integration: task('integration').merge({ - accessUserId: task('createdBy') - }) - })) - }).run() - } catch (e) { - // noop - } - // add index - try { - await r.table('Task').indexCreate('integrationHash').run() - } catch (e) { - // noop - } -} - -export const down = async function (r: R) { - await r.table('Task').indexDrop('integrationHash').run() - await r - .table('Task') - .filter((task) => task('integrationHash').default(null).ne(null)) - .replace((row) => row.without('integrationHash')) - .run() -} diff --git a/packages/server/database/migrations/20210726140543-estimate-stage-tasks.ts b/packages/server/database/migrations/20210726140543-estimate-stage-tasks.ts deleted file mode 100644 index 938bf3763ba..00000000000 --- a/packages/server/database/migrations/20210726140543-estimate-stage-tasks.ts +++ /dev/null @@ -1,149 +0,0 @@ -import JiraIssueId from 'parabol-client/shared/gqlIds/JiraIssueId' -import {R} from 'rethinkdb-ts' -import dndNoise from '../../../client/utils/dndNoise' -import convertToTaskContent from '../../../client/utils/draftjs/convertToTaskContent' -import generateUID from '../../generateUID' -import {getTemplateRefsByIds, insertTaskEstimate} from '../../postgres/generatedMigrationHelpers' -import EstimatePhase from '../types/EstimatePhase' - -export const up = async function (r: R) { - const BATCH_SIZE = 1000 - const plaintextContent = `Task imported from jira` - const content = convertToTaskContent(plaintextContent) - const updateStagesWithTaskIds = ( - meetingId: string, - stageIdTaskIdLookup: Record - ) => { - return r - .table('NewMeeting') - .get(meetingId) - .update((meeting) => ({ - phases: meeting('phases').map((phase) => - r.branch( - phase('phaseType').eq('ESTIMATE'), - phase.merge({ - stages: phase('stages').map((stage) => - stage.merge({ - taskId: r.branch( - stage('taskId'), - stage('taskId'), - r(stageIdTaskIdLookup)(stage('id')).default(stage('serviceTaskId')) - ) - }) - ) - }), - phase - ) - ) - })) - .run() - } - - for (let i = 0; i < 1e6; i++) { - const skip = i * BATCH_SIZE - console.log('migrating meeting #', skip) - const curMeetings = await r - .table('NewMeeting') - .filter({meetingType: 'poker'}) - .orderBy('createdAt') - .skip(skip) - .limit(BATCH_SIZE) - .run() - if (curMeetings.length < 1) break - // - const tasksToInsert = [] - const estimatesToInsert = [] - const stageUpdates = curMeetings.map(async (meeting) => { - const {id: meetingId, teamId, phases, templateRefId} = meeting - const [templateRef] = await getTemplateRefsByIds([templateRefId]) - const phase = phases.find((phase) => phase.phaseType === 'ESTIMATE') as EstimatePhase - if (!phase) return - const {stages} = phase - const stageIdToTaskId = {} as Record - stages.forEach((stage) => { - if (stage.taskId) return - const { - id: stageId, - service, - serviceTaskId, - creatorUserId, - finalScore, - startAt, - dimensionRefIdx, - discussionId - } = stage - // in case there was a hiccup with pg - const dimensionName = templateRef?.dimensions?.[dimensionRefIdx]?.name ?? 'Story Points' - let taskId = serviceTaskId - if (service === 'jira') { - const {cloudId, issueKey, projectKey} = JiraIssueId.split(serviceTaskId) - taskId = generateUID() - // turn it into a parabol task - const task = { - content, - plaintextContent, - createdAt: new Date(), - createdBy: creatorUserId, - meetingId, - sortOrder: dndNoise(), - status: 'future', - tags: ['archived'], - teamId, - integrationHash: serviceTaskId, - integration: { - service: 'jira', - cloudId, - issueKey, - projectKey, - accessUserId: creatorUserId - }, - userId: creatorUserId, - id: taskId, - updatedAt: new Date() - } - tasksToInsert.push(task) - stageIdToTaskId[stageId] = taskId - } - if (finalScore !== null && finalScore !== undefined) { - const estimate = { - changeSource: 'meeting', - createdAt: startAt || meeting.createdAt, - name: dimensionName, - label: finalScore, - taskId, - userId: creatorUserId, - meetingId, - stageId, - discussionId, - jiraFieldId: null - } - estimatesToInsert.push(estimate) - } - }) - return updateStagesWithTaskIds(meetingId, stageIdToTaskId) - }) - try { - await Promise.all(stageUpdates) - } catch (e) { - console.log('error updating stage taskId', e) - } - console.log({taskCount: tasksToInsert.length, estimateCount: estimatesToInsert.length}) - try { - if (tasksToInsert.length > 0) { - await r.table('Task').insert(tasksToInsert).run() - } - } catch (e) { - console.log('error inserting tasks', e) - } - - try { - await Promise.all(estimatesToInsert.map((estimate) => insertTaskEstimate(estimate))) - } catch (e) { - console.log('error inserting tasks', e) - } - } -} - -export const down = async function () { - // noop. it's just a taskId field & there's no way to discriminate between old vs new -} diff --git a/packages/server/database/migrations/20210817223727-removePromptTemplateId.ts b/packages/server/database/migrations/20210817223727-removePromptTemplateId.ts deleted file mode 100644 index d877111c955..00000000000 --- a/packages/server/database/migrations/20210817223727-removePromptTemplateId.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .update((row) => ({ - phases: row('phases').without('promptTemplateId') - })) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .update((meeting) => ({ - phases: meeting('phases').map((phase) => - phase('phaseType') - .eq('reflect') - .branch(phase.merge({promptTemplateId: meeting('templateId')}), phase) - ) - })) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20211025134235-estimateStageTaskIdBackfill.ts b/packages/server/database/migrations/20211025134235-estimateStageTaskIdBackfill.ts deleted file mode 100644 index 53da8f51c41..00000000000 --- a/packages/server/database/migrations/20211025134235-estimateStageTaskIdBackfill.ts +++ /dev/null @@ -1,149 +0,0 @@ -import JiraIssueId from 'parabol-client/shared/gqlIds/JiraIssueId' -import {R} from 'rethinkdb-ts' -import dndNoise from '../../../client/utils/dndNoise' -import convertToTaskContent from '../../../client/utils/draftjs/convertToTaskContent' -import generateUID from '../../generateUID' -import {getTemplateRefsByIds, insertTaskEstimate} from '../../postgres/generatedMigrationHelpers' -import EstimatePhase from '../types/EstimatePhase' - -export const up = async function (r: R) { - const BATCH_SIZE = 1000 - const plaintextContent = `Task imported from jira` - const content = convertToTaskContent(plaintextContent) - const updateStagesWithTaskIds = ( - meetingId: string, - stageIdTaskIdLookup: Record - ) => { - return r - .table('NewMeeting') - .get(meetingId) - .update((meeting) => ({ - phases: meeting('phases').map((phase) => - r.branch( - phase('phaseType').eq('ESTIMATE'), - phase.merge({ - stages: phase('stages').map((stage) => - r.branch( - stage.hasFields('taskId').not(), - stage.merge({ - taskId: r(stageIdTaskIdLookup)(stage('id')).default(stage('serviceTaskId')) - }), - stage - ) - ) - }), - phase - ) - ) - })) - .run() - } - - for (let i = 0; i < 1e6; i++) { - const skip = i * BATCH_SIZE - console.log('migrating meeting #', skip) - const curMeetings = await r - .table('NewMeeting') - .filter({meetingType: 'poker'}) - .orderBy('createdAt') - .skip(skip) - .limit(BATCH_SIZE) - .run() - if (curMeetings.length < 1) break - // - const tasksToInsert = [] - const estimatesToInsert = [] - const stageUpdates = curMeetings.map(async (meeting) => { - const {id: meetingId, teamId, phases, templateRefId} = meeting - const [templateRef] = await getTemplateRefsByIds([templateRefId]) - const phase = phases.find((phase) => phase.phaseType === 'ESTIMATE') as EstimatePhase - if (!phase) return - const {stages} = phase - const stageIdToTaskId = {} as Record - stages.forEach((stage) => { - if (stage.taskId) return - const { - id: stageId, - service, - serviceTaskId, - creatorUserId, - finalScore, - startAt, - dimensionRefIdx, - discussionId - } = stage - // in case there was a hiccup with pg - const dimensionName = templateRef?.dimensions?.[dimensionRefIdx]?.name ?? 'Story Points' - let taskId = serviceTaskId - if (service === 'jira') { - const {cloudId, issueKey, projectKey} = JiraIssueId.split(serviceTaskId) - taskId = generateUID() - // turn it into a parabol task - const task = { - content, - plaintextContent, - createdAt: new Date(), - createdBy: creatorUserId, - meetingId, - sortOrder: dndNoise(), - status: 'future', - tags: ['archived'], - teamId, - integrationHash: serviceTaskId, - integration: { - service: 'jira', - cloudId, - issueKey, - projectKey, - accessUserId: creatorUserId - }, - userId: creatorUserId, - id: taskId, - updatedAt: new Date() - } - tasksToInsert.push(task) - stageIdToTaskId[stageId] = taskId - } - if (finalScore !== null && finalScore !== undefined) { - const estimate = { - changeSource: 'meeting', - createdAt: startAt || meeting.createdAt, - name: dimensionName, - label: finalScore, - taskId, - userId: creatorUserId, - meetingId, - stageId, - discussionId, - jiraFieldId: null - } - estimatesToInsert.push(estimate) - } - }) - return updateStagesWithTaskIds(meetingId, stageIdToTaskId) - }) - try { - await Promise.all(stageUpdates) - } catch (e) { - console.log('error updating stage taskId', e) - } - console.log({taskCount: tasksToInsert.length, estimateCount: estimatesToInsert.length}) - try { - if (tasksToInsert.length > 0) { - await r.table('Task').insert(tasksToInsert).run() - } - } catch (e) { - console.log('error inserting tasks', e) - } - - try { - await Promise.all(estimatesToInsert.map((estimate) => insertTaskEstimate(estimate))) - } catch (e) { - console.log('error inserting tasks', e) - } - } -} - -export const down = async function () { - // noop. it's just a taskId field & there's no way to discriminate between old vs new -} diff --git a/packages/server/database/migrations/20220112175838-addMissingPlainTextContentToTask.ts b/packages/server/database/migrations/20220112175838-addMissingPlainTextContentToTask.ts deleted file mode 100644 index b69f54742a1..00000000000 --- a/packages/server/database/migrations/20220112175838-addMissingPlainTextContentToTask.ts +++ /dev/null @@ -1,46 +0,0 @@ -import extractTextFromDraftString from 'parabol-client/utils/draftjs/extractTextFromDraftString' -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - // We have about 2500 such tasks - const missedTasks = await r - .table('Task') - .filter((row) => row.hasFields('plaintextContent').not()) - .run() - - console.log('Missed tasks found:', missedTasks.length) - - if (missedTasks.length) { - const updates = [] as { - taskId: string - plaintextContent: string - }[] - for (const task of missedTasks) { - updates.push({ - taskId: task.id, - plaintextContent: extractTextFromDraftString(task.content) - }) - } - const updateResult = await r(updates) - .forEach((updateObj) => { - return r - .table('Task') - .get(updateObj('taskId')) - .update( - { - plaintextContent: updateObj('plaintextContent') - }, - { - returnChanges: true - } - ) - })('changes') - .run() - - console.log('Updated:', updateResult?.length) - } -} - -export const down = function () { - // noop -} diff --git a/packages/server/database/migrations/20220124600507-addMoreRetroTemplates.ts b/packages/server/database/migrations/20220124600507-addMoreRetroTemplates.ts deleted file mode 100644 index a7ce84233c3..00000000000 --- a/packages/server/database/migrations/20220124600507-addMoreRetroTemplates.ts +++ /dev/null @@ -1,671 +0,0 @@ -import {R} from 'rethinkdb-ts' -import {PALETTE} from '../../../client/styles/paletteV3' - -type PromptInput = { - question: string - description: string - templateId: string - sortOrder: number - promptColor?: string - promptId?: string -} - -const promptColors = [ - PALETTE.JADE_400, - PALETTE.TOMATO_500, - PALETTE.GOLD_300, - PALETTE.LILAC_500, - PALETTE.SKY_300, - PALETTE.TERRA_300, - PALETTE.FUSCIA_400, - PALETTE.SLATE_700 -] - -const nameToId = (name: string, isTemplate: boolean) => { - const cleanedName = name - .replace(/[^0-9a-z-A-Z ]/g, '') // remove emojis and apostrophes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${isTemplate ? 'Template' : 'Prompt'}` -} - -const templateNames = [ - 'Speed Car 🏎️', - 'WRAP 🧞', - 'Marie Kondo Retrospective 😌', - 'Original 4', - 'Rose, Thorn, Bud 🌹', - 'Hopes and Fears 🎭', - 'Surprised, Worried, Inspired 😯', - 'Superhero Retrospective 🦸', - 'Six Thinking Hats 🎩', - 'Hot Air Balloon 🎈', - 'Hero’s Journey 👑', - 'Keep, Problem, Try 🤔', - 'SaMoLo ⚖️', - 'SWOT Analysis 🎯', - 'Hands on Deck Activity 🚢', - 'Highlights & Lowlights 🎢', - 'New Year Retrospective 🗓️', - 'A Christmas Carol Retrospective 🎅🏼', - 'Always Be Learning Retrospective 🌱', - 'Dream Team Retrospective 🦄', - 'Thanksgiving Retrospective 🥧', - 'Diwali Retrospective 🪔', - 'Halloween Retrospective 🎃', - 'Questions, Comments, Concerns❓', - 'Team Retreat Planning 🌴' -] - -const promptsInfo = [ - { - templateId: nameToId('Speed Car 🏎️', true), - question: 'Engine', - description: 'What’s helping us move faster?', - sortOrder: 0 - }, - { - templateId: nameToId('Speed Car 🏎️', true), - question: 'Parachute', - description: 'What’s slowing us down?', - sortOrder: 1 - }, - { - templateId: nameToId('WRAP 🧞', true), - question: 'Wishes', - description: 'What are your wishes for the team or your work? What would make work better?', - sortOrder: 0 - }, - { - templateId: nameToId('WRAP 🧞', true), - question: 'Risks', - description: - 'What risks or challenges lie ahead? What was risky about our work in the last period?', - sortOrder: 1 - }, - { - templateId: nameToId('WRAP 🧞', true), - question: 'Appreciation', - description: 'Who made this sprint special or did exceptional work?', - sortOrder: 2 - }, - { - templateId: nameToId('WRAP 🧞', true), - question: 'Puzzles', - description: 'What unresolved questions do you have?', - sortOrder: 3 - }, - { - templateId: nameToId('Marie Kondo Retrospective 😌', true), - question: 'What Sparks Joy?', - description: 'What processes, tools, and skills are serving you well?', - sortOrder: 0 - }, - { - templateId: nameToId('Marie Kondo Retrospective 😌', true), - question: 'Thank you and Goodbye', - description: 'What do you want to stop doing, having, or using, or just stop from happening?', - sortOrder: 1 - }, - { - templateId: nameToId('Marie Kondo Retrospective 😌', true), - question: 'Things to Upcycle', - description: 'What could serve you well if it was changed or improved?', - sortOrder: 2 - }, - { - templateId: nameToId('Original 4', true), - question: 'Wins 🏆', - description: 'What did we do well, that we should discuss so we don’t forget?', - sortOrder: 0 - }, - { - templateId: nameToId('Original 4', true), - question: 'Learnings 🎓 ', - description: 'What did we learn?', - sortOrder: 1 - }, - { - templateId: nameToId('Original 4', true), - question: 'Improvements ♻️ ', - description: 'What should we do differently next time?', - sortOrder: 2 - }, - { - templateId: nameToId('Original 4', true), - question: 'Questions ❓', - description: 'What still puzzles us?', - sortOrder: 3 - }, - { - templateId: nameToId('Rose, Thorn, Bud 🌹', true), - question: 'Rose', - description: 'What went well? Which of our current practices or skills are strong?', - sortOrder: 0 - }, - { - templateId: nameToId('Rose, Thorn, Bud 🌹', true), - question: 'Thorn', - description: 'What challenges or difficulties did we run into?', - sortOrder: 1 - }, - { - templateId: nameToId('Rose, Thorn, Bud 🌹', true), - question: 'Bud', - description: 'What are our opportunities for growth and improvement?', - sortOrder: 2 - }, - { - templateId: nameToId('Hopes and Fears 🎭', true), - question: 'Hopes 🙏', - promptId: 'hopesPrompt-2', - description: 'What do you hope for in the next period?', - sortOrder: 0 - }, - { - templateId: nameToId('Hopes and Fears 🎭', true), - question: 'Fears 🧟 ', - description: 'What are you worried about for the next period?', - sortOrder: 1 - }, - { - templateId: nameToId('Surprised, Worried, Inspired 😯', true), - question: 'Surprised', - description: 'What caught you off guard, positively or negatively?', - sortOrder: 0 - }, - { - templateId: nameToId('Surprised, Worried, Inspired 😯', true), - question: 'Worried', - description: 'What are you anxious about?', - sortOrder: 1 - }, - { - templateId: nameToId('Surprised, Worried, Inspired 😯', true), - question: 'Inspired', - description: 'What has you energized for the future?', - sortOrder: 2 - }, - { - templateId: nameToId('Superhero Retrospective 🦸', true), - question: 'Superpower', - description: 'What are your strongest skills?', - sortOrder: 0 - }, - { - templateId: nameToId('Superhero Retrospective 🦸', true), - question: 'Gadgets', - description: 'What people, tools, or processes are most helpful?', - sortOrder: 1 - }, - { - templateId: nameToId('Superhero Retrospective 🦸', true), - question: 'Nemesis', - description: 'What makes your role more difficult?', - sortOrder: 2 - }, - { - templateId: nameToId('Superhero Retrospective 🦸', true), - question: 'Role', - description: - 'Where do you fit into the team? How do you see your role interacting with others?', - sortOrder: 3 - }, - { - templateId: nameToId('Six Thinking Hats 🎩', true), - question: 'Blue Hat', - promptColor: PALETTE.SKY_400, - description: 'What do we want to achieve in this session?', - sortOrder: 0 - }, - { - templateId: nameToId('Six Thinking Hats 🎩', true), - question: 'White Hat', - promptColor: PALETTE.SLATE_100, - description: 'What are the facts or information we have about the last sprint?', - sortOrder: 1 - }, - { - templateId: nameToId('Six Thinking Hats 🎩', true), - question: 'Yellow Hat', - promptColor: PALETTE.GOLD_300, - description: 'What was good about the last sprint?', - sortOrder: 2 - }, - { - templateId: nameToId('Six Thinking Hats 🎩', true), - question: 'Black Hat', - promptColor: PALETTE.SLATE_900_32, - description: 'What was bad about the last sprint?', - sortOrder: 3 - }, - { - templateId: nameToId('Six Thinking Hats 🎩', true), - question: 'Green Hat', - promptColor: PALETTE.JADE_400, - description: 'What things could improve for our next sprint?', - sortOrder: 4 - }, - { - templateId: nameToId('Six Thinking Hats 🎩', true), - question: 'Red Hat', - promptColor: PALETTE.TOMATO_700, - description: 'What’s your overall feeling about the previous sprint?', - sortOrder: 5 - }, - { - templateId: nameToId('Hot Air Balloon 🎈', true), - question: 'Hot Air', - description: - 'Looking back, what practices or processes elevate our team and help us reach great new heights?', - sortOrder: 0 - }, - { - templateId: nameToId('Hot Air Balloon 🎈', true), - question: 'Sandbags', - description: - 'Looking back, what practices or processes are dragging us down, making us slow, or demoralizing us?', - sortOrder: 1 - }, - { - templateId: nameToId('Hot Air Balloon 🎈', true), - question: 'Storm Clouds', - description: - 'Looking ahead, what difficult or tricky things are in store for our team? What things could throw us off course or be dangerous?', - sortOrder: 2 - }, - { - templateId: nameToId('Hot Air Balloon 🎈', true), - question: 'Clear Skies', - description: - 'Looking ahead, how could we avoid or manage threats and challenges? How could we push through them to reach clearer skies?', - sortOrder: 3 - }, - { - templateId: nameToId('Hero’s Journey 👑', true), - question: 'Hero', - description: 'What are the attitudes and characteristics that make our team heroic?', - sortOrder: 0 - }, - { - templateId: nameToId('Hero’s Journey 👑', true), - question: 'Guide', - description: 'What guidance or help do you need to be successful?', - sortOrder: 1 - }, - { - templateId: nameToId('Hero’s Journey 👑', true), - question: 'Treasure', - description: 'What’s your team’s end goal? What does success look like?', - sortOrder: 2 - }, - { - templateId: nameToId('Hero’s Journey 👑', true), - question: 'Cavern', - description: 'What challenges lie ahead?', - sortOrder: 3 - }, - { - templateId: nameToId('Keep, Problem, Try 🤔', true), - question: 'Keep', - description: 'What should we continue doing?', - sortOrder: 0 - }, - { - templateId: nameToId('Keep, Problem, Try 🤔', true), - question: 'Problem', - description: 'What’s not going well?', - sortOrder: 1 - }, - { - templateId: nameToId('Keep, Problem, Try 🤔', true), - question: 'Try', - description: 'What’s the smallest next step we could take to resolve our problems?', - sortOrder: 2 - }, - { - templateId: nameToId('SaMoLo ⚖️', true), - question: 'Same of', - description: 'What do we want to keep doing?', - sortOrder: 0 - }, - { - templateId: nameToId('SaMoLo ⚖️', true), - question: 'More of', - description: 'What do we want to do more of?', - sortOrder: 1 - }, - { - templateId: nameToId('SaMoLo ⚖️', true), - question: 'Less of', - description: 'What do we want to do less of?', - sortOrder: 2 - }, - { - templateId: nameToId('SWOT Analysis 🎯', true), - question: 'Stengths', - description: 'What are we good at?', - sortOrder: 0 - }, - { - templateId: nameToId('SWOT Analysis 🎯', true), - question: 'Weaknesses', - description: 'What needs more work?', - sortOrder: 1 - }, - { - templateId: nameToId('SWOT Analysis 🎯', true), - question: 'Opportunities', - description: 'Where can we improve or what can we take advantage of?', - sortOrder: 2 - }, - { - templateId: nameToId('SWOT Analysis 🎯', true), - question: 'Threats', - description: 'What could be negative or dangerous to us?', - sortOrder: 3 - }, - { - templateId: nameToId('Hands on Deck Activity 🚢', true), - question: 'Captain 🧑‍✈️', - description: - 'What things do you see yourself leading on? What things do you want to lead the team on? What do you want to take responsibility for?', - sortOrder: 0 - }, - { - templateId: nameToId('Hands on Deck Activity 🚢', true), - question: 'First Mate ✋', - description: - 'What do you want to support closely? What work do you want to have a clear say in?', - sortOrder: 1 - }, - { - templateId: nameToId('Hands on Deck Activity 🚢', true), - question: 'Navigator 🧭', - description: - 'What are the things you want to avoid, either as a team or in your specific role?', - sortOrder: 2 - }, - { - templateId: nameToId('Hands on Deck Activity 🚢', true), - question: 'Deck Scrubber 🧼', - description: 'What are you happy to help out with, but would rather take a back seat on?', - sortOrder: 3 - }, - { - templateId: nameToId('Highlights & Lowlights 🎢', true), - question: 'Highlights 🙌 ', - description: 'What was great or exceeded expectations?', - sortOrder: 0 - }, - { - templateId: nameToId('Highlights & Lowlights 🎢', true), - question: 'Lowlights 😫 ', - description: 'What didn’t go well or made us feel down?', - sortOrder: 1 - }, - { - templateId: nameToId('Highlights & Lowlights 🎢', true), - question: 'Kudos ❤️', - description: 'Who helped you or deserves some appreciation?', - sortOrder: 2 - }, - { - templateId: nameToId('New Year Retrospective 🗓️', true), - question: 'Growth & Wisdom 🌱 ', - description: - 'Looking back, how did you grow and what did you learn as an individual or as a team?', - sortOrder: 0 - }, - { - templateId: nameToId('New Year Retrospective 🗓️', true), - question: 'Greatest Hits 🏆', - description: 'Looking back, what were your or the team’s greatest accomplishments', - sortOrder: 1 - }, - { - templateId: nameToId('New Year Retrospective 🗓️', true), - question: 'Resolutions 🗓️', - description: - 'Looking ahead, how can we improve? What things can we work on or commit to for the future.', - sortOrder: 2 - }, - { - templateId: nameToId('A Christmas Carol Retrospective 🎅🏼', true), - question: 'Christmas Past 👻', - description: - 'What’s your biggest regret about the year? What do you wish you could have changed?', - sortOrder: 0 - }, - { - templateId: nameToId('A Christmas Carol Retrospective 🎅🏼', true), - question: 'Christmas Present 🎄', - description: - 'What are you grateful for? Who has helped you? What processes, skills, or tools make work better? Share some kudos!', - sortOrder: 1 - }, - { - templateId: nameToId('A Christmas Carol Retrospective 🎅🏼', true), - question: 'Christmas Future ⭐ ', - description: 'What are your personal or team aspirations for the year ahead?', - sortOrder: 2 - }, - { - templateId: nameToId('A Christmas Carol Retrospective 🎅🏼', true), - question: 'All I want for Christmas is… 🎁', - description: - 'What’s your Christmas wish for the team? What would make your work easier or relieve a burden?', - sortOrder: 3 - }, - { - templateId: nameToId('Always Be Learning Retrospective 🌱', true), - question: 'Things I learned 🎓', - description: 'What have you learned as an individual or a team in the last period?', - sortOrder: 0 - }, - { - templateId: nameToId('Always Be Learning Retrospective 🌱', true), - question: 'Things I want to learn 🧠', - description: - 'What are the priority things you want to learn as an individual or as a team in the next period?', - sortOrder: 1 - }, - { - templateId: nameToId('Dream Team Retrospective 🦄', true), - question: 'Practices ⚙️', - description: 'What habits, practises, or processes helped the team work well together?', - sortOrder: 0 - }, - { - templateId: nameToId('Dream Team Retrospective 🦄', true), - question: 'Values 💜', - description: 'What values and teamwork principles make us successful', - sortOrder: 1 - }, - { - templateId: nameToId('Dream Team Retrospective 🦄', true), - question: 'Absence 🤔', - description: 'What practices, processes or skills weren’t present in the team?', - sortOrder: 2 - }, - { - templateId: nameToId('Thanksgiving Retrospective 🥧', true), - question: 'Old Favorites 🦃', - description: 'What tried-and-true practices or habits are serving us well?', - sortOrder: 0 - }, - { - templateId: nameToId('Thanksgiving Retrospective 🥧', true), - question: 'New Traditions 🍟', - description: 'What new things did we try or learn?', - sortOrder: 1 - }, - { - templateId: nameToId('Thanksgiving Retrospective 🥧', true), - question: 'Left on the Table 🐌', - description: 'What do we wish we’d left behind, or should leave behind from now on?', - sortOrder: 2 - }, - { - templateId: nameToId('Thanksgiving Retrospective 🥧', true), - question: 'Gratitude 🍰', - description: 'What are you thankful for?', - sortOrder: 3 - }, - { - templateId: nameToId('Diwali Retrospective 🪔', true), - question: 'Diyas', - description: 'What do we need to guide us forward or help us find our way?', - sortOrder: 0 - }, - { - templateId: nameToId('Diwali Retrospective 🪔', true), - question: 'Rangoli', - description: 'What practices or processes are bringing positivity?', - sortOrder: 1 - }, - { - templateId: nameToId('Diwali Retrospective 🪔', true), - question: 'Lakshmi', - description: - 'What do we need to tidy or clean up? What processes or backlog items need purifying?', - sortOrder: 2 - }, - { - templateId: nameToId('Diwali Retrospective 🪔', true), - question: 'Ravana', - description: 'What demons, projects, or problems are cursing us?', - sortOrder: 3 - }, - { - templateId: nameToId('Halloween Retrospective 🎃', true), - question: 'Ghosts 👻', - description: 'Boo! What projects or issues caught us by surprise?', - sortOrder: 0 - }, - { - templateId: nameToId('Halloween Retrospective 🎃', true), - question: 'Zombies 🧟', - description: 'What feels slow? What are we dragging our feet on?', - sortOrder: 1 - }, - { - templateId: nameToId('Halloween Retrospective 🎃', true), - question: 'Brains 🧠', - description: 'What did we learn? What do we need to learn?', - sortOrder: 2 - }, - { - templateId: nameToId('Halloween Retrospective 🎃', true), - question: 'Candy 🍬', - description: 'Who deserves candy? What went well? Who do you want to give kudos to?', - sortOrder: 3 - }, - { - templateId: nameToId('Questions, Comments, Concerns❓', true), - question: 'Questions ❓', - promptId: 'questionsPrompt-2', - description: - 'What isn’t clear about this proposal, decision, or idea? What needs further explanation?', - sortOrder: 0 - }, - { - templateId: nameToId('Questions, Comments, Concerns❓', true), - question: 'Comments 💬', - description: 'What reactions do you have to this proposal, decision, or idea?', - sortOrder: 1 - }, - { - templateId: nameToId('Questions, Comments, Concerns❓', true), - question: 'Concerns 🧐', - description: 'What worries do you have about this proposal, decision, or idea?', - sortOrder: 2 - }, - { - templateId: nameToId('Team Retreat Planning 🌴', true), - question: 'Hopes 🙏', - description: - 'What do you hope we will do together? What do you hope will come from our time together?', - sortOrder: 0 - }, - { - promptId: 'fearsPrompt-2', - templateId: nameToId('Team Retreat Planning 🌴', true), - question: 'Fears 🧟', - description: 'What concerns do you have about the retreat? What are you worried about?', - sortOrder: 1 - }, - { - templateId: nameToId('Team Retreat Planning 🌴', true), - question: 'Project/Problem 💡', - description: 'What project should we explore? What problem should we tackle together?', - sortOrder: 2 - } -] as const - -const createdAt = new Date() -const makeTemplate = (name: string) => ({ - createdAt, - id: nameToId(name, true), - isActive: true, - name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true -}) - -const makePrompt = (promptInfo: PromptInput, idx: number) => { - const {question, description, promptColor, promptId, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColor ? promptColor : promptColors[paletteIdx] - // FIXME this creates duplicated ids - const id = promptId ? promptId : nameToId(question, false) - return { - createdAt, - description, - groupColor, - id, - isActive: true, - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - title: question, - updatedAt: createdAt - } -} - -export const templates = templateNames.map((templateName) => makeTemplate(templateName)) -export const reflectPrompts = promptsInfo.map((promptInfo, idx) => makePrompt(promptInfo, idx)) - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20220222141104-updateThreeLittlePigsPromptColors.ts b/packages/server/database/migrations/20220222141104-updateThreeLittlePigsPromptColors.ts deleted file mode 100644 index d18f4cd9ce8..00000000000 --- a/packages/server/database/migrations/20220222141104-updateThreeLittlePigsPromptColors.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {R} from 'rethinkdb-ts' -import {PALETTE} from '../../../client/styles/paletteV3' - -export const up = async function (r: R) { - try { - await r({ - houseOfBricks: r - .table('ReflectPrompt') - .get('promptHouseOfBricks') - .update({groupColor: PALETTE.JADE_400}), - houseOfSticks: r - .table('ReflectPrompt') - .get('promptHouseOfSticks') - .update({groupColor: PALETTE.TOMATO_700}), - houseOfStraw: r - .table('ReflectPrompt') - .get('promptHouseOfStraw') - .update({groupColor: PALETTE.GOLD_300}) - }).run() - } catch (e) { - console.error('error when migration up groupColors for the threeLittlePigsTemplate', e) - } -} - -export const down = async function (r: R) { - try { - await r({ - houseOfBricks: r - .table('ReflectPrompt') - .get('promptHouseOfBricks') - .update({groupColor: '#D9D916'}), - houseOfSticks: r - .table('ReflectPrompt') - .get('promptHouseOfSticks') - .update({groupColor: '#E55C5C'}), - houseOfStraw: r - .table('ReflectPrompt') - .get('promptHouseOfStraw') - .update({groupColor: '#52CC52'}) - }).run() - } catch (e) { - console.error('error when migrating down groupColors for the threeLittlePigsTemplate', e) - } -} diff --git a/packages/server/database/migrations/20220329101759-dropTeams.ts b/packages/server/database/migrations/20220329101759-dropTeams.ts deleted file mode 100644 index d3f900073bb..00000000000 --- a/packages/server/database/migrations/20220329101759-dropTeams.ts +++ /dev/null @@ -1,43 +0,0 @@ -import getPg, {closePg} from '../../postgres/getPg' -import {Team} from '../../postgres/queries/getTeamsByIds' -import {closeRethink} from '../rethinkDriver' - -export const up = async function (r) { - const pg = await getPg() - - const teamTableExists = await pg.query<{exists: boolean}>( - `SELECT EXISTS (SELECT 1 FROM "pg_tables" WHERE tablename = 'Team');` - ) - - await r.tableDrop('Team').run() - - await Promise.all([closePg(), closeRethink()]) -} - -export const down = async function (r) { - if (await r.tableList().contains('Team').run()) return - await r.tableCreate('Team').run() - await r.table('Team').indexCreate('orgId').run() - await r.table('Team').indexCreate('updatedAt').run() - await r.table('Team').indexWait().run() - - const pg = await getPg() - const teams = await pg.query(`SELECT * FROM "Team";`) - - const batchSize = 1000 - - function dropUndefined(object: any) { - Object.keys(object).forEach((key) => { - if (object[key] === undefined) { - delete object[key] - } - }) - } - - for (let current = 0; current * batchSize < teams.rowCount; current += batchSize) { - const filteredTeams = teams.rows.slice(current, current + batchSize).map(dropUndefined) - await r.table('Team').insert(filteredTeams).run() - } - - await closePg() -} diff --git a/packages/server/database/migrations/20220524131406-addPromptToTeamPrompt.ts b/packages/server/database/migrations/20220524131406-addPromptToTeamPrompt.ts deleted file mode 100644 index 678b7337544..00000000000 --- a/packages/server/database/migrations/20220524131406-addPromptToTeamPrompt.ts +++ /dev/null @@ -1,25 +0,0 @@ -export const up = async function (r) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'teamPrompt'}) - .update({ - meetingPrompt: 'What are you working on today? Stuck on anything?' - }) - .run() - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - try { - await r - .table('NewMeeting') - .filter({meetingType: 'teamPrompt'}) - .replace(r.row.without('meetingPrompt')) - .run() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20220602164119-fixRetroTemplates.ts b/packages/server/database/migrations/20220602164119-fixRetroTemplates.ts deleted file mode 100644 index 730ea2e689d..00000000000 --- a/packages/server/database/migrations/20220602164119-fixRetroTemplates.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - down as faultyDown, - up as faultyUp, - reflectPrompts, - templates -} from './20220124600507-addMoreRetroTemplates' - -const fixedReflectPrompts = reflectPrompts.map((prompt) => ({ - ...prompt, - id: `${prompt.templateId}:${prompt.id}` -})) - -export const up = async function (r) { - try { - await faultyDown(r) - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(fixedReflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r) { - const templateIds = templates.map(({id}) => id) - const promptIds = fixedReflectPrompts.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - await faultyUp(r) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20220610093935-fixRetroPromptIds.ts b/packages/server/database/migrations/20220610093935-fixRetroPromptIds.ts deleted file mode 100644 index 64b4390903d..00000000000 --- a/packages/server/database/migrations/20220610093935-fixRetroPromptIds.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {reflectPrompts} from './20220124600507-addMoreRetroTemplates' - -// fix promptId fields of existing reflections -const promptIdMapping = reflectPrompts - // filter out prompts which were missing since the old id belongs to different template - .filter(({id}) => !['keepPrompt', 'moreOfPrompt', 'lessOfPrompt'].includes(id)) - .map(({id, templateId}) => ({ - oldId: id, - newId: `${templateId}:${id}` - })) - -// There is some prompt filtering happening based on template creation date -const newIds = reflectPrompts.map(({id, templateId}) => `${templateId}:${id}`) -const createdAt = new Date('2022-01-28') - -export const up = async function (r) { - await r.table('ReflectPrompt').getAll(r.args(newIds)).update({createdAt}).run() - - await r.table('RetroReflection').indexCreate('promptId').run() - await r.table('RetroReflectionGroup').indexCreate('promptId').run() - await r.table('RetroReflection').indexWait().run() - await r.table('RetroReflectionGroup').indexWait().run() - - for (const {oldId, newId} of promptIdMapping) { - await r({ - retroReflection: r - .table('RetroReflection') - .getAll(oldId, {index: 'promptId'}) - .update({promptId: newId}), - retroReflectionGroup: r - .table('RetroReflectionGroup') - .getAll(oldId, {index: 'promptId'}) - .update({promptId: newId}) - }).run() - } -} - -export const down = async function (r) { - for (const {oldId, newId} of promptIdMapping) { - await r({ - retroReflection: r - .table('RetroReflection') - .getAll(newId, {index: 'promptId'}) - .update({promptId: oldId}), - retroReflectionGroup: r - .table('RetroReflectionGroup') - .getAll(newId, {index: 'promptId'}) - .update({promptId: oldId}) - }).run() - } - await r.table('RetroReflection').indexDrop('promptId').run() - await r.table('RetroReflectionGroup').indexDrop('promptId').run() -} diff --git a/packages/server/database/migrations/20220614155505-addTeamCharterTemplate.ts b/packages/server/database/migrations/20220614155505-addTeamCharterTemplate.ts deleted file mode 100644 index b6b9288d46f..00000000000 --- a/packages/server/database/migrations/20220614155505-addTeamCharterTemplate.ts +++ /dev/null @@ -1,125 +0,0 @@ -import {R} from 'rethinkdb-ts' -import {PALETTE} from '../../../client/styles/paletteV3' - -type PromptInput = { - question: string - description: string - templateId: string - sortOrder: number - promptColor?: string - promptId?: string -} - -const promptColors = [ - PALETTE.JADE_400, - PALETTE.TOMATO_500, - PALETTE.GOLD_300, - PALETTE.LILAC_500, - PALETTE.SKY_300, - PALETTE.TERRA_300, - PALETTE.FUSCIA_400, - PALETTE.SLATE_700 -] - -const nameToId = (name: string, isTemplate: boolean) => { - const cleanedName = name - .replace(/[^0-9a-z-A-Z ]/g, '') // remove emojis and apostrophes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${isTemplate ? 'Template' : 'Prompt'}` -} - -const templateNames = ['Team Charter'] - -const promptsInfo = [ - { - templateId: nameToId('Team Charter', true), - question: 'Mission', - description: `What's the overall mission of our team?`, - sortOrder: 0 - }, - { - templateId: nameToId('Team Charter', true), - question: 'Values', - description: `What values guide our work together and with others?`, - sortOrder: 1 - }, - { - templateId: nameToId('Team Charter', true), - question: 'Achievements', - description: `What are we setting out to achieve together? What differentiates us? How do we measure success?`, - sortOrder: 2 - }, - { - templateId: nameToId('Team Charter', true), - question: 'Responsibilities', - description: `What is our team responsible for?`, - sortOrder: 3 - } -] as const - -const createdAt = new Date() -const makeTemplate = (name: string) => ({ - createdAt, - id: nameToId(name, true), - isActive: true, - name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true -}) - -const makePrompt = (promptInfo: PromptInput, idx: number) => { - const {question, description, promptColor, promptId, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColor ? promptColor : promptColors[paletteIdx] - const id = promptId ? promptId : nameToId(`${templateId}:${question}`, false) - return { - createdAt, - description, - groupColor, - id, - isActive: true, - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - title: question, - updatedAt: createdAt - } -} - -export const templates = templateNames.map((templateName) => makeTemplate(templateName)) -export const reflectPrompts = promptsInfo.map((promptInfo, idx) => makePrompt(promptInfo, idx)) - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20220815156512-addScrumValuesTemplate.ts b/packages/server/database/migrations/20220815156512-addScrumValuesTemplate.ts deleted file mode 100644 index 0e112253ebe..00000000000 --- a/packages/server/database/migrations/20220815156512-addScrumValuesTemplate.ts +++ /dev/null @@ -1,130 +0,0 @@ -import {R} from 'rethinkdb-ts' -import {PALETTE} from '../../../client/styles/paletteV3' - -type PromptInput = { - question: string - description: string - templateId: string - sortOrder: number - promptColor?: string - promptId?: string -} - -const promptColors = [ - PALETTE.JADE_400, - PALETTE.TOMATO_500, - PALETTE.GOLD_300, - PALETTE.LILAC_500, - PALETTE.SKY_300, - PALETTE.TERRA_300, - PALETTE.FUSCIA_400, - PALETTE.SLATE_700 -] - -const nameToId = (name: string, isTemplate: boolean) => { - const cleanedName = name - .replace(/[^0-9a-z-A-Z ]/g, '') // remove emojis and apostrophes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${isTemplate ? 'Template' : 'Prompt'}` -} -const templateNames = ['Scrum Values Retrospective'] - -const promptsInfo = [ - { - templateId: nameToId('Scrum Values Retrospective', true), - question: 'Commitment', - description: `Scrum Teams are committed to achieving their goals and to supporting each other. What are some examples of us doing this well? In what cases have we struggled or failed to be committed?`, - sortOrder: 0 - }, - { - templateId: nameToId('Scrum Values Retrospective', true), - question: 'Focus', - description: `A Scrum Team's primary focus is on the work of the Sprint to make the best possible progress toward the sprint goal. What's helping us focus? When have we struggled to stay focused?`, - sortOrder: 1 - }, - { - templateId: nameToId('Scrum Values Retrospective', true), - question: 'Openness', - description: `Scrum Teams are open about their work and the challenges they face. How could we improve transparency in our work? What practices are helping us be more open about our work?`, - sortOrder: 2 - }, - { - templateId: nameToId('Scrum Values Retrospective', true), - question: 'Respect', - description: `Scrum Team members respect each other to be capable, independent people, and are respected as such by the people with whom they work. What practices help us practice respect and build psychological safety? Are there cases when we have struggled with this?`, - sortOrder: 3 - }, - { - templateId: nameToId('Scrum Values Retrospective', true), - question: 'Courage', - description: `Scrum Teams have the courage to do the right thing and to work on tough problems. Are there any times when we struggled to be courageous or didn't do the right thing?`, - sortOrder: 4 - } -] as const - -const createdAt = new Date() -const makeTemplate = (name: string) => ({ - createdAt, - id: nameToId(name, true), - isActive: true, - name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true -}) - -const makePrompt = (promptInfo: PromptInput, idx: number) => { - const {question, description, promptColor, promptId, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColor ? promptColor : promptColors[paletteIdx] - const id = promptId ? promptId : nameToId(`${templateId}:${question}`, false) - return { - createdAt, - description, - groupColor, - id, - isActive: true, - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - title: question, - updatedAt: createdAt - } -} - -export const templates = templateNames.map((templateName) => makeTemplate(templateName)) -export const reflectPrompts = promptsInfo.map((promptInfo, idx) => makePrompt(promptInfo, idx)) - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20220815231343-addDisableAnonymity.ts b/packages/server/database/migrations/20220815231343-addDisableAnonymity.ts deleted file mode 100644 index 88043c48c4e..00000000000 --- a/packages/server/database/migrations/20220815231343-addDisableAnonymity.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r - .table('MeetingSettings') - .filter((row) => row.hasFields('disableAnonymity').not()) - .update({disableAnonymity: false}) - .run() -} - -export const down = async function (r: R) { - await r - .table('MeetingSettings') - .replace((row) => row.without('disableAnonymity')) - .run() -} diff --git a/packages/server/database/migrations/20220819072356-addMeetingSeriesIdIndex.ts b/packages/server/database/migrations/20220819072356-addMeetingSeriesIdIndex.ts deleted file mode 100644 index 6bf6370ffa4..00000000000 --- a/packages/server/database/migrations/20220819072356-addMeetingSeriesIdIndex.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r.table('NewMeeting').indexCreate('meetingSeriesId').run() -} - -export const down = async function (r: R) { - await r.table('NewMeeting').indexDrop('meetingSeriesId').run() -} diff --git a/packages/server/database/migrations/20220819183021-createScheduledMeetingEndIndices.ts b/packages/server/database/migrations/20220819183021-createScheduledMeetingEndIndices.ts deleted file mode 100644 index 1b19661eba9..00000000000 --- a/packages/server/database/migrations/20220819183021-createScheduledMeetingEndIndices.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r - .table('NewMeeting') - .indexCreate('hasEndedScheduledEndTime', [ - r.row.hasFields('endedAt'), - r.row('scheduledEndTime') - ]) - .run() -} - -export const down = async function (r: R) { - await r.table('NewMeeting').indexDrop('hasEndedScheduledEndTime').run() -} diff --git a/packages/server/database/migrations/20221012142324-fixDakiMigration.ts b/packages/server/database/migrations/20221012142324-fixDakiMigration.ts deleted file mode 100644 index 49bc1afdcad..00000000000 --- a/packages/server/database/migrations/20221012142324-fixDakiMigration.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - const now = new Date() - const missingKeepPrompt = { - createdAt: now, - description: 'What should we continue doing?', - groupColor: '#D9D916', - id: 'keepPrompt', - isActive: true, - question: 'Keep', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'dropAddKeepImproveDAKITemplate', - title: 'Keep', - updatedAt: now - } - await r.table('ReflectPrompt').insert(missingKeepPrompt).run() -} - -export const down = async function (r: R) { - await r.table('ReflectPrompt').get('keepPrompt').delete().run() -} diff --git a/packages/server/database/migrations/20221021163318-rename-christmas-template.ts b/packages/server/database/migrations/20221021163318-rename-christmas-template.ts deleted file mode 100644 index 1865fa48e8f..00000000000 --- a/packages/server/database/migrations/20221021163318-rename-christmas-template.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - await r - .table('MeetingTemplate') - .get('aChristmasCarolRetrospectiveTemplate') - .update({name: 'Christmas Retrospective 🎅🏼'}) - .run() -} - -export const down = async function (r: R) { - await r - .table('MeetingTemplate') - .get('aChristmasCarolRetrospectiveTemplate') - .update({name: 'A Christmas Carol Retrospective 🎅🏼'}) - .run() -} diff --git a/packages/server/database/migrations/20221025161717-addIsFreeMeetingTemplate.ts b/packages/server/database/migrations/20221025161717-addIsFreeMeetingTemplate.ts deleted file mode 100644 index 6da07bfdfdf..00000000000 --- a/packages/server/database/migrations/20221025161717-addIsFreeMeetingTemplate.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const freeTemplateIds = [ - 'startStopContinueTemplate', - 'gladSadMadTemplate', - 'whatWentWellTemplate', - 'workingStuckTemplate', - 'sailboatTemplate', - 'original4Template', - 'fourLsTemplate' -] - -export const up = async function (r: R) { - await r.table('MeetingTemplate').getAll(r.args(freeTemplateIds)).update({isFree: true}).run() -} -export const down = async function (r: R) { - await r - .table('MeetingTemplate') - .getAll(r.args(freeTemplateIds)) - .replace((row) => row.without('isFree')) - .run() -} diff --git a/packages/server/database/migrations/20221107145022-makePokerPublicTemplatesFree.ts b/packages/server/database/migrations/20221107145022-makePokerPublicTemplatesFree.ts deleted file mode 100644 index 7f65def4163..00000000000 --- a/packages/server/database/migrations/20221107145022-makePokerPublicTemplatesFree.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {R} from 'rethinkdb-ts' - -const freeTemplateIds = ['estimatedEffortTemplate', 'wsjfTemplate'] - -export const up = async function (r: R) { - await r.table('MeetingTemplate').getAll(r.args(freeTemplateIds)).update({isFree: true}).run() -} -export const down = async function (r: R) { - await r - .table('MeetingTemplate') - .getAll(r.args(freeTemplateIds)) - .replace((row) => row.without('isFree')) - .run() -} diff --git a/packages/server/database/migrations/20221107180234-adjustUserTiers.ts b/packages/server/database/migrations/20221107180234-adjustUserTiers.ts deleted file mode 100644 index 9d767bf5ced..00000000000 --- a/packages/server/database/migrations/20221107180234-adjustUserTiers.ts +++ /dev/null @@ -1,80 +0,0 @@ -import {R, RDatum, RValue} from 'rethinkdb-ts' -import getPg, {closePg} from '../../postgres/getPg' -import {TierEnum} from '../types/Invoice' -import OrganizationUser from '../types/OrganizationUser' -import User from '../types/User' - -export const up = async function (r: R) { - const removedOrgUserIds = await r - .table('OrganizationUser') - .hasFields('removedAt') - .filter((row) => row('tier').ne('personal'))('userId') - .distinct() - .run() - - await r - .table('User') - .getAll(r.args(removedOrgUserIds)) - .update( - (user: RDatum) => ({ - tier: r - .table('OrganizationUser') - .getAll(user('id'), {index: 'userId'}) - .filter({removedAt: null})('orgId') - .coerceTo('array') - .distinct() - .do((orgIds: RValue) => - r.table('Organization').getAll(r.args(orgIds))('tier').distinct().coerceTo('array') - ) - .do((tiers: RDatum) => { - return r.branch( - tiers.contains('enterprise'), - 'enterprise', - tiers.contains('pro'), - 'pro', - 'personal' - ) - }) - }), - {nonAtomic: true} - ) - .run() - - const userTiers = (await r - .table('OrganizationUser') - .getAll(r.args(removedOrgUserIds), {index: 'userId'}) - .filter({removedAt: null}) - .merge((orgUser: RDatum) => ({ - tier: r.table('Organization').get(orgUser('orgId'))('tier').default('personal') - })) - .group('userId')('tier') - .ungroup() - .map((row) => ({ - id: row('group'), - tier: r.branch( - row('reduction').contains('enterprise'), - 'enterprise', - row('reduction').contains('pro'), - 'pro', - 'personal' - ) - })) - .run()) as {id: string; tier: TierEnum}[] - - const pg = getPg() - await Promise.all( - userTiers.map((userTier) => { - return pg.query( - `UPDATE "User" AS u SET "tier" = $1::"TierEnum" - WHERE $2 = u."id"; - `, - [userTier.tier, userTier.id] - ) - }) - ) - closePg() -} - -export const down = function (r: R) { - // noop -} diff --git a/packages/server/database/migrations/20221201121536-addHeardSeenRespectedTemplate.ts b/packages/server/database/migrations/20221201121536-addHeardSeenRespectedTemplate.ts deleted file mode 100644 index 79825f86ee6..00000000000 --- a/packages/server/database/migrations/20221201121536-addHeardSeenRespectedTemplate.ts +++ /dev/null @@ -1,112 +0,0 @@ -import {R} from 'rethinkdb-ts' -import {PALETTE} from '../../../client/styles/paletteV3' - -const createdAt = new Date() - -const makeId = (name: string, type: 'template' | 'prompt') => { - const cleanedName = name - .replace(/[^0-9a-z-A-Z ]/g, '') // remove emojis and apostrophes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${type === 'template' ? 'Template' : 'Prompt'}` -} - -const makeTemplate = (name: string) => ({ - createdAt, - id: makeId(name, 'template'), - isActive: true, - name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true, - isFree: false -}) - -type PromptInfo = { - question: string - description: string - groupColor: string - templateId: string - sortOrder: number -} - -const makePrompt = (promptInfo: PromptInfo) => { - const {question, description, groupColor, templateId, sortOrder} = promptInfo - return { - createdAt, - description, - groupColor, - id: makeId(`${templateId}:${question}`, 'prompt'), - isActive: true, - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - title: question, - updatedAt: createdAt - } -} - -const templateName = 'Heard, Seen, Respected (HSR)' - -const promptsInfo = [ - { - question: 'Heard', - description: - 'Think about times or forums in which you felt your voice was not heard. What happened? How did it feel?', - groupColor: PALETTE.GRAPE_600, - templateId: makeId(templateName, 'template'), - sortOrder: 0 - }, - { - question: 'Seen', - description: - 'Think about times or forums in which you felt you were not seen or your efforts were not recognized. What happened? How did it feel?', - groupColor: PALETTE.TOMATO_600, - templateId: makeId(templateName, 'template'), - sortOrder: 1 - }, - { - question: 'Respected', - description: - 'Think about times or forums in which you felt you, your boundaries, or your contributions were not respected. What happened? How did it feel?', - groupColor: PALETTE.SKY_400, - templateId: makeId(templateName, 'template'), - sortOrder: 2 - } -] as const - -const template = makeTemplate(templateName) -const reflectPrompts = promptsInfo.map((promptInfo) => makePrompt(promptInfo)) - -export const up = async function (r: R) { - try { - await Promise.all([ - r.table('MeetingTemplate').insert(template).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - } catch (e) { - console.log(e) - } -} - -export const down = async function (r: R) { - const templateId = template.id - const promptIds = reflectPrompts.map(({id}) => id) - try { - await Promise.all([ - r.table('MeetingTemplate').get(templateId).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/database/migrations/20221220161224-updateTier.ts b/packages/server/database/migrations/20221220161224-updateTier.ts deleted file mode 100644 index 201eb4d3c94..00000000000 --- a/packages/server/database/migrations/20221220161224-updateTier.ts +++ /dev/null @@ -1,138 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - const BATCH_SIZE = 750 - for (let i = 0; i < 1e5; i++) { - const skip = i * BATCH_SIZE - const res = await Promise.all([ - r - .table('Organization') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('personal'), - 'starter', - r.branch(row('tier').eq('pro'), 'team', row('tier')) - ) - })) - .run(), - r - .table('OrganizationUser') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').default(null).eq('personal'), - 'starter', - r.branch(row('tier').default(null).eq('pro'), 'team', row('tier').default(null)) - ), - suggestedTier: r.branch( - row('suggestedTier').default(null).eq('personal'), - 'starter', - r.branch( - row('suggestedTier').default(null).eq('pro'), - 'team', - row('suggestedTier').default(null) - ) - ) - })) - .run(), - r - .table('Invoice') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('personal'), - 'starter', - r.branch(row('tier').eq('pro'), 'team', row('tier')) - ) - })) - .run(), - r - .table('User') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('personal'), - 'starter', - r.branch(row('tier').eq('pro'), 'team', row('tier')) - ) - })) - .run() - ]) - - const isComplete = res.every( - (res) => res.skipped === 0 && res.unchanged === 0 && res.errors === 0 && res.replaced === 0 - ) - if (isComplete) break - } -} - -export const down = async function (r: R) { - const BATCH_SIZE = 750 - for (let i = 0; i < 1e5; i++) { - const skip = i * BATCH_SIZE - const res = await Promise.all([ - r - .table('Organization') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('starter'), - 'personal', - r.branch(row('tier').eq('team'), 'pro', row('tier')) - ) - })) - .run(), - r - .table('OrganizationUser') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('starter'), - 'personal', - r.branch(row('tier').eq('team'), 'pro', row('tier')) - ), - suggestedTier: r.branch( - row('suggestedTier').eq('starter'), - 'personal', - r.branch(row('suggestedTier').eq('team'), 'pro', row('suggestedTier').default(null)) - ) - })) - .run(), - r - .table('Invoice') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('starter'), - 'personal', - r.branch(row('tier').eq('team'), 'pro', row('tier')) - ) - })) - .run(), - r - .table('User') - .skip(skip) - .limit(BATCH_SIZE) - .update((row) => ({ - tier: r.branch( - row('tier').eq('starter'), - 'personal', - r.branch(row('tier').eq('team'), 'pro', row('tier')) - ) - })) - .run() - ]) - const isComplete = res.every( - (res) => res.skipped === 0 && res.unchanged === 0 && res.errors === 0 && res.replaced === 0 - ) - if (isComplete) break - } -} diff --git a/packages/server/database/migrations/20230116165620-fixStarfishTemplate.ts b/packages/server/database/migrations/20230116165620-fixStarfishTemplate.ts deleted file mode 100644 index 795c1530964..00000000000 --- a/packages/server/database/migrations/20230116165620-fixStarfishTemplate.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {R} from 'rethinkdb-ts' - -export const up = async function (r: R) { - const now = new Date() - const missingLessOfPrompt = { - createdAt: now, - description: 'What are we over-doing or doing too much of?', - groupColor: '#D9D916', - id: 'starfishTemplate:lessOfPrompt', - isActive: true, - question: 'Less Of ➖', - sortOrder: 1, - teamId: 'aGhostTeam', - templateId: 'starfishTemplate', - title: 'Less Of ➖', - updatedAt: now - } - const missingMoreOfPrompt = { - createdAt: now, - description: 'What are we not taking enough advantage of?', - groupColor: '#45E5E5', - id: 'starfishTemplate:moreOfPrompt', - isActive: true, - question: 'More Of ➕', - sortOrder: 2, - teamId: 'aGhostTeam', - templateId: 'starfishTemplate', - title: 'More Of ➕', - updatedAt: now - } - - await r - .table('ReflectPrompt') - .insert([missingLessOfPrompt, missingMoreOfPrompt], {conflict: 'error'}) - .run() -} - -export const down = async function (r: R) { - await r - .table('ReflectPrompt') - .getAll(r.args(['starfishTemplate:lessOfPrompt', 'starfishTemplate:moreOfPrompt'])) - .delete() - .run() -} diff --git a/packages/server/database/readCert.ts b/packages/server/database/readCert.ts deleted file mode 100644 index 5d2f8bb9be1..00000000000 --- a/packages/server/database/readCert.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {readFileSync} from 'fs' -import {join} from 'path' - -export default function readCert() { - return readFileSync(join(__dirname, 'cacert'), 'utf8') -} diff --git a/packages/server/database/rethinkDriver.ts b/packages/server/database/rethinkDriver.ts deleted file mode 100644 index 1b2078fdcfc..00000000000 --- a/packages/server/database/rethinkDriver.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {MasterPool, r} from 'rethinkdb-ts' -import getRethinkConfig from './getRethinkConfig' -import {R} from './stricterR' - -export type RethinkSchema = {} - -export type DBType = { - [P in keyof RethinkSchema]: any -} - -export type ParabolR = R -const config = getRethinkConfig() -let isLoading = false -let isLoaded = false -let promise: Promise | undefined -const getRethink = async () => { - if (!isLoaded) { - if (!isLoading) { - isLoading = true - promise = r.connectPool(config) - } - await promise - isLoaded = true - } - // this is important because pm2 will restart the process & for whatever reason r isn't always healthy - await r.waitForHealthy() - return r as unknown as ParabolR -} - -export const closeRethink = async () => { - if (promise) { - await (await promise).drain() - isLoaded = false - isLoading = false - promise = undefined - } -} - -export default getRethink diff --git a/packages/server/database/stricterR.ts b/packages/server/database/stricterR.ts deleted file mode 100644 index 434b2cd3434..00000000000 --- a/packages/server/database/stricterR.ts +++ /dev/null @@ -1,1718 +0,0 @@ -/*eslint-disable*/ -import {EventEmitter} from 'events' -import {TcpNetConnectOpts} from 'net' -import {ConnectionOptions} from 'tls' - -type DeepPartial = - | RValue - | { - [P in keyof T]?: T[P] extends Array - ? Array> - : T[P] extends ReadonlyArray - ? ReadonlyArray> - : DeepPartial - } - -// User defined schemas -export interface TableSchema { - type: any - index: string -} - -export interface UserSchema { - [tableName: string]: TableSchema -} - -//#region optargs -export type Primitives = null | string | boolean | number -export type Format = 'native' | 'raw' -export type Durability = 'hard' | 'soft' -export type RValue = RDatum | T -// TODO: Add recursive type when option available -// type RValue = T extends RDatum -// ? T -// : T extends null | string | number | boolean -// ? RDatum -// : T extends Array -// ? RArray : T extends Function ? never : T extends object ? { [P in keyof T]: RValue } : never; -// type RObject = { -// [x: keyof T]: RValue; -// } | RDatum; -export type Func = (doc: RDatum) => RValue -export type MultiFieldSelector = object | any[] | string -export type FieldSelector = string | Func - -export interface ServerInfo { - id: string - name: string - proxy: boolean -} - -export type RServerConnectionOptions = - | (Partial & {tls: boolean}) - | (Partial & {tls?: false}) - -export interface RBaseConnectionOptions { - db?: string // default 'test' - user?: string // default 'admin' - password?: string // default '' - discovery?: boolean // default false - pool?: boolean // default true - buffer?: number // default = number of servers - max?: number // default = number of servers - timeout?: number // default = 20 - pingInterval?: number // default -1 - timeoutError?: number // default = 1000 - timeoutGb?: number // default = 60*60*1000 - maxExponent?: number // default 6 - silent?: boolean // default = false - log?: (message: string) => any // default undefined; - [other: string]: any -} - -export type RConnectionOptions = RBaseConnectionOptions & - ({server: RServerConnectionOptions} | {host?: string; port?: number}) - -export type RPoolConnectionOptions = RConnectionOptions & { - servers?: RServerConnectionOptions[] - waitForHealthy?: boolean // default true -} -export interface TableCreateOptions { - primaryKey?: string // default: "id" - shards?: number // 1-32 - replicas?: number | {[serverTag: string]: number} - primaryReplicaTag?: string - nonvotingReplicaTags?: string[] - durability?: Durability // "soft" or "hard" defualt: "hard" -} - -export interface TableReconfigureOptions { - shards?: number // 1-32 - replicas?: number | {[serverTag: string]: number} - primaryReplicaTag?: string - dryRun?: boolean - emergencyRepair?: 'unsafe_rollback' | 'unsafe_rollback_or_erase' -} - -export interface TableOptions { - readMode?: 'single' | 'majority' | 'outdated' | 'primary' - identifierFormat?: 'name' | 'uuid' // "name" "uuid"; -} - -export interface DeleteOptions { - ignoreWriteHook?: boolean - returnChanges?: boolean | string | 'always' // true, false or "always" default: false - durability?: Durability // "soft" or "hard" defualt: table -} - -export interface InsertOptions extends DeleteOptions { - conflict?: - | 'error' - | 'replace' - | 'update' - | ((id: RDatum, oldDoc: RDatum, newDoc: RDatum) => RDatum | object) -} - -export interface UpdateOptions extends DeleteOptions { - nonAtomic?: boolean -} - -export interface IndexOptions { - multi?: boolean - geo?: boolean -} - -export interface RunOptions { - timeFormat?: Format | 'ISO8601' // 'native' or 'raw', default 'native' - groupFormat?: Format // 'native' or 'raw', default 'native' - binaryFormat?: Format // 'native' or 'raw', default 'native' - useOutdated?: boolean // default false - profile?: boolean // default false - durability?: Durability // 'hard' or 'soft' - noreply?: boolean // default false - db?: string - arrayLimit?: number // default 100,000 - minBatchRows?: number // default 8 - maxBatchRows?: number - maxBatchRow?: number // default unlimited - maxBatchBytes?: number // default 1MB - maxBatchSeconds?: number // default 0.5 - firstBatchScaledownFactor?: number // default 4 - readMode?: 'single' | 'majority' | 'outdated' -} - -export interface HttpRequestOptions { - // General - timeout?: number // default 30 - reattempts?: number // default 5 - redirects?: number // default 1 - verify?: boolean // default true - resultFormat?: 'text' | 'json' | 'jsonp' | 'binary' | 'auto' - - // Request Options - method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' // "GET" "POST" "PUT" "PATCH" "DELETE" "HEAD" - params?: object - header?: {[key: string]: string | object} - data?: object -} - -export interface HTTPStreamRequestOptions extends HttpRequestOptions { - // Pagination - page?: 'link-next' | ((param: RDatum<{params: any; header: any; body: any}>) => RValue) - pageLimit?: number // -1 = no limit. -} - -export interface WaitOptions { - waitFor?: - | 'ready_for_outdated_reads' - | 'ready_for_reads' - | 'ready_for_writes' - | 'all_replicas_ready' - timeout?: number -} - -export interface ChangesOptions { - squash?: boolean | number - changefeedQueueSize?: number - includeInitial?: boolean - includeStates?: boolean - includeTypes?: boolean - includeOffsets?: boolean -} -//#endregion optargs - -//#region results -export interface ValueChange { - error?: string - old_val?: T - new_val?: T -} -export interface DBConfig { - id: string - name: string -} -export interface DBChangeResult { - config_changes: Array> - tables_dropped: number - dbs_created: number - dbs_dropped: number -} -export interface IndexChangeResult { - created?: number - renamed?: number - dropped?: number -} -export interface RebalanceResult { - reconfigured: number - config_changes: Array> - status_changes: Array> -} -export interface ReconfigureResult { - rebalanced: number - status_changes: Array> -} -export interface TableChangeResult { - tables_created?: number - tables_dropped?: number - config_changes: Array> -} - -export interface TableShard { - primary_replica: string - replicas: string[] - nonvoting_replicas: string[] -} - -export interface TableConfig { - id: string - name: string - db: string - primary_key: string // default: "id" - shards: TableShard[] - indexes: string[] - write_acks: string - durability: Durability // "soft" or "hard" defualt: "hard" -} -export interface TableStatus { - id: string - name: string - db: string - status: { - all_replicas_ready: boolean - ready_for_outdated_reads: boolean - ready_for_reads: boolean - ready_for_writes: boolean - } - shards: TableShard[] -} -export interface IndexStatus { - function: Buffer - geo: boolean - index: string - multi: boolean - outdated: boolean - ready: boolean -} -export interface WriteResult { - deleted: number - skipped: number - errors: number - first_error?: string - inserted: number - replaced: number - unchanged: number - generated_keys?: string[] - warnings?: string[] - changes?: Array> -} -export interface Changes extends ValueChange { - state?: 'initializing' | 'ready' // 'initializing', 'ready'. cant come together with values - type?: 'change' | 'add' | 'remove' | 'initial' | 'uninitial' | 'state' - old_offset?: number - new_offset?: number -} - -export interface JoinResult { - left: T1 - right: T2 -} - -export interface GroupResults { - group: TGroupBy - reduction: TReduction -} - -export interface MatchResults { - start: number - end: number - str: string - groups: Array<{ - start: number - end: number - str: string - }> -} - -//#endregion results - -//#region operations -export interface Connection extends EventEmitter { - readonly open: boolean - clientPort: number - clientAddress: string - close(options?: {noreplyWait: boolean}): Promise - reconnect(options?: {noreplyWait: boolean}): Promise - use(db: string): void - noreplyWait(): Promise - server(): Promise -} - -export interface MasterPool extends EventEmitter { - readonly isHealthy: boolean - waitForHealthy(): Promise - drain(options?: {noreplyWait: boolean}): Promise - getLength(): number - getAvailableLength(): number - getPools(): ConnectionPool[] - setOptions(options: { - discovery?: boolean - buffer?: number - max?: number - timeoutError?: number - timeoutGb?: number - maxExponent?: number - silent?: boolean - log?: (msg: string) => void - }): void -} -export interface ConnectionPool extends EventEmitter { - readonly isHealthy: boolean - - drain(options?: {noreplyWait: boolean}): Promise - getLength(): number - getAvailableLength(): number - getConnections(): Connection[] -} - -export interface RServer { - host: string - port: number -} - -export type RCursorType = - | 'Atom' - | 'Cursor' - | 'Feed' - | 'AtomFeed' - | 'OrderByLimitFeed' - | 'UnionedFeed' -export interface RCursor extends NodeJS.ReadableStream { - readonly profile: any - getType(): RCursorType - next(): Promise - toArray(): Promise - close(): Promise - each( - callback: (err: RethinkDBError | undefined, row: any) => any, - onFinishedCallback?: () => any - ): Promise - eachAsync( - rowHandler: (row: any, rowFinished?: (error?: any) => any) => any, - final?: (error: any) => any - ): Promise -} - -export interface RethinkDBError extends Error { - readonly type: RethinkDBErrorType -} - -export enum RethinkDBErrorType { - UNKNOWN, - // driver - API_FAIL, - // query errors - CONNECTION, - MASTER_POOL_FAIL, - POOL_FAIL, - CURSOR_END, - TIMEOUT, - CANCEL, - PARSE, - ARITY, - CURSOR, - // connection error - AUTH, - UNSUPPORTED_PROTOCOL, - // reql response errors - INTERNAL, - RESOURCE_LIMIT, - QUERY_LOGIC, - NON_EXISTENCE, - OP_FAILED, - OP_INDETERMINATE, - USER, - PERMISSION_ERROR -} - -export interface RQuery { - typeOf(): RDatum - info(): RDatum<{ - value?: string - db?: {id: string; name: string; type: string} - doc_count_estimates?: number[] - id?: string - indexes?: string[] - name?: string - primary_key?: string - type: string - }> - - run(options: RunOptions & {noreply: true}): Promise - run(connection: Connection, options: RunOptions & {noreply: true}): Promise - run(options: RunOptions & {profile: true}): Promise<{profile: any; result: T}> - run( - connection: Connection, - options: RunOptions & {profile: true} - ): Promise<{profile: any; result: T}> - run(connection?: Connection | RunOptions, options?: RunOptions): Promise - getCursor( - connection?: Connection | RunOptions, - options?: RunOptions - ): T extends Array - ? Promise> - : T extends RCursor - ? Promise - : Promise> - then(): never -} -export interface RDatum extends RQuery { - do( - ...args: Array, ...args: RDatum[]) => U)> - ): U extends RStream ? RStream : RDatum - (attribute: RValue): U extends keyof T ? RDatum : RDatum - getField( - attribute: RValue - ): U extends keyof T ? RDatum : RDatum - nth(attribute: RValue): T extends Array ? RDatum : never - default(value: U): RDatum - hasFields(...fields: string[]): T extends Array ? RDatum : RDatum - // Works only if T is an array - append(value: RValue): T extends U[] ? RDatum : never - prepend(value: RValue): T extends U[] ? RDatum : never - difference(value: RValue): T extends U[] ? RDatum : never - setInsert(value: RValue): T extends U[] ? RDatum : never - setUnion(value: RValue): T extends U[] ? RDatum : never - setIntersection(value: RValue): T extends U[] ? RDatum : never - setDifference(value: RValue): T extends U[] ? RDatum : never - insertAt(index: RValue, value: RValue): T extends U[] ? RDatum : never - changeAt(index: RValue, value: RValue): T extends U[] ? RDatum : never - spliceAt(index: RValue, value: RValue): T extends U[] ? RDatum : never - deleteAt(offset: RValue, endOffset?: RValue): T extends U[] ? RDatum : never - union ? T1 : never>( - ...other: Array | RValue | {interleave: boolean | string}> - ): T extends any[] ? RDatum : never - map ? T1 : never>( - ...args: Array, ...args: RDatum[]) => any)> - ): T extends any[] ? RDatum : never - concatMap ? T1 : never>( - ...args: Array, ...args: RDatum[]) => Res)> - ): T extends ArrayLike ? RDatum : never - forEach< - U = any, - ONE = T extends Array ? T1 : never, - RES extends - | RDatum> - | RDatum - | RDatum = RDatum> - >( - func: (res: RDatum) => RES - ): T extends any[] ? RES : never - - withFields( - ...fields: MultiFieldSelector[] - ): T extends Array ? RDatum>> : never - filter ? T1 : never>( - predicate: DeepPartial | ((doc: RDatum) => RValue), - options?: {default: boolean} - ): this - includes(geometry: RDatum): T extends Array ? RDatum : never - intersects(geometry: RDatum): T extends Array ? RDatum : never - - // LOGIC - contains ? T1 : never>( - val1: any[] | null | string | number | object | Func, - ...value: Array> - ): T extends Array ? RDatum : never // also predicate - - // ORDER BY - orderBy(...fields: Array>): T extends Array ? RDatum : never - - // GROUP - group(...fieldOrFunc: Array>): T extends Array ? RDatum : never // >; - - ungroup(): RDatum>> - - // SELECT FUNCTIONS - count ? T1 : never>( - value?: RValue | Func - ): T extends Array ? RDatum : never - sum ? T1 : never>( - value?: FieldSelector - ): T extends Array ? RDatum : never - avg ? T1 : never>( - value?: FieldSelector - ): T extends Array ? RDatum : never - min ? T1 : never>( - value?: FieldSelector - ): T extends Array ? RDatum : never - max ? T1 : never>( - value?: FieldSelector - ): T extends Array ? RDatum : never - reduce ? T1 : never>( - reduceFunction: (left: RDatum, right: RDatum) => any - ): T extends Array ? RDatum : never - fold ? T1 : never>( - base: any, - foldFunction: (acc: RDatum, next: RDatum) => any, // this any is ACC - options?: { - emit?: ( - acc: RDatum, - next: RDatum, - // tslint:disable-next-line:variable-name - new_acc: RDatum - ) => any[] // this any is RES - finalEmit?: (acc: RStream) => any[] // this any is also RES - } - ): T extends Array ? RDatum : never - // SELECT - distinct(): RDatum - - pluck( - ...fields: MultiFieldSelector[] - ): T extends Array ? RDatum>> : RDatum> - - without( - ...fields: MultiFieldSelector[] - ): T extends Array ? RDatum>> : RDatum> - - merge(...objects: Array) => any)>): RDatum - - innerJoin ? T1 : never>( - other: RStream | RValue, - predicate: (doc1: RDatum, doc2: RDatum) => RValue - ): RDatum>> - outerJoin ? T1 : never>( - other: RStream | RValue, - predicate: (doc1: RDatum, doc2: RDatum) => RValue - ): RDatum>> // actually left join - eqJoin ? T1 : never>( - fieldOrPredicate: RValue | Func, - rightTable: RTable, - options?: {index: string} - ): RStream> - skip(n: RValue): T extends Array ? RDatum : never - limit(n: RValue): T extends Array ? RDatum : never - slice( - start: RValue, - end?: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): T extends Array ? RDatum : never - slice( - start: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): T extends Array ? RDatum : never - sample(n: RValue): T extends Array ? RDatum : never - offsetsOf ? T1 : never>( - single: RValue | Func - ): T extends Array ? RDatum : never - - isEmpty(): T extends Array ? RDatum : never - - coerceTo(type: 'object' | 'OBJECT'): T extends Array ? RDatum : never - coerceTo(type: 'string' | 'STRING'): RDatum - coerceTo( - type: 'array' | 'ARRAY' - ): T extends ArrayLike> ? RDatum : RDatum - // Works only if T is a string - coerceTo(type: 'number' | 'NUMBER'): T extends string ? RDatum : never - coerceTo(type: 'binary' | 'BINARY'): T extends string ? RDatum : never - match(regexp: RValue): T extends string ? RDatum : never - split( - seperator?: RValue, - maxSplits?: RValue - ): T extends string ? RDatum : never - upcase(): T extends string ? RDatum : never - downcase(): T extends string ? RDatum : never - add( - ...str: Array | RValue> - ): T extends string | number | Date ? RDatum : never - gt( - ...value: Array | RValue | RValue> - ): T extends string | number | Date ? RDatum : never - ge( - ...value: Array | RValue | RValue> - ): T extends string | number | Date ? RDatum : never - lt( - ...value: Array | RValue | RValue> - ): T extends string | number | Date ? RDatum : never - le( - ...value: Array | RValue | RValue> - ): T extends string | number | Date ? RDatum : never - // Works only for numbers - sub( - ...num: Array> - ): T extends number ? RDatum : T extends Date ? RDatum : never - sub(date: RValue): T extends Date ? RDatum : never - mul(...num: Array>): T extends number ? RDatum : never - div(...num: Array>): T extends number ? RDatum : never - mod(...num: Array>): T extends number ? RDatum : never - - bitAnd(...num: Array>): T extends number ? RDatum : never - bitOr(...num: Array>): T extends number ? RDatum : never - bitXor(...num: Array>): T extends number ? RDatum : never - bitNot(...num: Array>): T extends number ? RDatum : never - bitSal(...num: Array>): T extends number ? RDatum : never - bitShl(...num: Array>): T extends number ? RDatum : never - bitSar(...num: Array>): T extends number ? RDatum : never - bitSht(...num: Array>): T extends number ? RDatum : never - - round(): T extends number ? RDatum : never - ceil(): T extends number ? RDatum : never - floor(): T extends number ? RDatum : never - // Works only for bool - branch( - trueBranch: any, - falseBranchOrTest: any, - ...branches: any[] - ): T extends boolean ? RDatum : never - and(...bool: Array>): T extends boolean ? RDatum : never - or(...bool: Array>): T extends boolean ? RDatum : never - not(): T extends boolean ? RDatum : never - // Works only for Date - inTimezone(timezone: string): T extends Date ? RDatum : never - timezone(): T extends Date ? RDatum : never - during( - start: RValue, - end: RValue, - options?: {leftBound: 'open' | 'closed'; rightBound: 'open' | 'closed'} - ): T extends Date ? RDatum : never - date(): T extends Date ? RDatum : never - timeOfDay(): T extends Date ? RDatum : never - year(): T extends Date ? RDatum : never - month(): T extends Date ? RDatum : never - day(): T extends Date ? RDatum : never - dayOfWeek(): T extends Date ? RDatum : never - dayOfYear(): T extends Date ? RDatum : never - hours(): T extends Date ? RDatum : never - minutes(): T extends Date ? RDatum : never - seconds(): T extends Date ? RDatum : never - toISO8601(): T extends Date ? RDatum : never - toEpochTime(): T extends Date ? RDatum : never - // Works only for geo - distance(geo: RValue, options?: {geoSystem?: string; unit?: string}): RDatum - toGeojson(): RDatum - // Works only for line - fill(): RDatum - polygonSub(polygon2: RValue): RDatum - - toJsonString(): RDatum - toJSON(): RDatum - - eq(...value: RValue[]): RDatum - ne(...value: RValue[]): RDatum - - keys(): RDatum - values(): RDatum> -} - -export interface RStream extends RQuery { - forEach< - U = any, - RES extends - | RDatum> - | RDatum - | RDatum = RDatum> - >( - func: (res: RDatum) => RES - ): RES - changes(options?: ChangesOptions): RFeed> - - (attribute: RValue): RStream - (n: RValue): RDatum - getField(fieldName: RValue): RStream - - // FROM - - innerJoin( - other: RStream | RValue, - predicate: (doc1: RDatum, doc2: RDatum) => RValue - ): RStream> - outerJoin( - other: RStream | RValue, - predicate: (doc1: RDatum, doc2: RDatum) => RValue - ): RStream> // actually left join - eqJoin( - fieldOrPredicate: RValue | Func, - rightTable: RTable, - options?: {index: string} - ): RStream> - - zip(): T extends JoinResult ? U1 & U2 : never - - union( - ...other: Array | RValue | {interleave: boolean | string}> - ): RStream - union( - ...other: Array | RValue | RFeed | {interleave: boolean | string}> - ): RFeed - map(...args: Array, ...args: RDatum[]) => any)>): RStream - concatMap( - ...args: Array, ...args: RDatum[]) => any)> - ): RStream - - // WHERE - withFields(...fields: MultiFieldSelector[]): RStream> - hasFields(...fields: MultiFieldSelector[]): RStream - filter( - predicate: DeepPartial | ((doc: RDatum) => RValue), - options?: {default: boolean} - ): this - includes(geometry: RDatum): RStream - intersects(geometry: RDatum): RStream - - // LOGIC - contains( - val1: any[] | null | string | number | object | Func, - ...value: Array> - ): RDatum - - // ORDER BY - orderBy(...fieldOrIndex: Array | {index: string}>): this // also r.desc(string) - - // GROUP - group( - ...fieldOrFunc: Array) => any) | {index?: string; multi?: boolean}> - ): T extends Array ? RDatum : never // >; - - // SELECT FUNCTIONS - count(value?: RValue | Func): RDatum - sum(value?: RValue | Func): RDatum - avg(value?: RValue | Func): RDatum - min(value?: RValue | Func | {index: string}): RDatum - max(value?: RValue | Func | {index: string}): RDatum - reduce(reduceFunction: (left: RDatum, right: RDatum) => any): RDatum - fold( - base: any, - foldFunction: (acc: RDatum, next: RDatum) => any, // this any is ACC - options?: { - // tslint:disable-next-line:variable-name - emit?: (acc: RDatum, next: RDatum, new_acc: RDatum) => any[] // this any is RES - finalEmit?: (acc: RStream) => any[] // this any is also RES - } - ): RStream - // SELECT - distinct(): RStream - distinct(index: {index: string}): RStream - - pluck(...fields: MultiFieldSelector[]): RStream> - without(...fields: MultiFieldSelector[]): RStream> - - merge(...objects: Array) => any)>): RStream - - skip(n: RValue): this - limit(n: RValue): this - slice( - start: RValue, - end?: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): this - slice( - start: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): this - nth(n: RValue): RDatum - sample(n: RValue): this - offsetsOf(single: RValue | Func): RDatum - - isEmpty(): RDatum - - coerceTo(type: 'array'): RDatum - coerceTo(type: 'object'): RDatum -} - -export interface RFeed extends RQuery> { - (attribute: RValue): RFeed - getField(fieldName: RValue): RFeed - - union( - ...other: Array | RValue | RFeed | {interleave: boolean | string}> - ): RFeed - map(...args: Array, ...args: RDatum[]) => any)>): RFeed - concatMap( - ...args: Array, ...args: RDatum[]) => any)> - ): RFeed - - // WHERE - - withFields(...fields: MultiFieldSelector[]): RFeed> - hasFields(...fields: MultiFieldSelector[]): RFeed - filter( - predicate: DeepPartial | ((doc: RDatum) => RValue), - options?: {default: boolean} - ): this - includes(geometry: RDatum): RFeed - intersects(geometry: RDatum): RFeed - - fold( - base: any, - foldFunction: (acc: RDatum, next: RDatum) => any, // this any is ACC - options: { - emit: (acc: RDatum, next: RDatum, newAcc: RDatum) => any[] // this any is RES - } - ): RFeed - - pluck(...fields: MultiFieldSelector[]): RFeed> - without(...fields: MultiFieldSelector[]): RFeed> -} - -export interface RSingleSelection extends RDatum { - update( - obj: RValue> | ((arg: RDatum) => any), - options?: UpdateOptions - ): RDatum> - replace( - obj: RValue | ((arg: RDatum) => any), - options?: UpdateOptions - ): RDatum> - delete(options?: DeleteOptions): RDatum> - changes(options?: ChangesOptions): RFeed> -} - -export interface RSelection extends RStream { - update( - obj: RValue> | ((arg: RDatum) => any), - options?: UpdateOptions - ): RDatum> - replace( - obj: RValue | ((arg: RDatum) => any), - options?: UpdateOptions - ): RDatum> - delete(options?: DeleteOptions): RDatum> - nth(n: RValue): RSingleSelection -} -export interface RTable extends RSelection { - grant( - userName: string, - options?: { - read?: boolean - write?: boolean - connect?: boolean - config?: boolean - } - ): RDatum<{ - granted: number - permissions_changes: Array< - ValueChange<{ - read: boolean - write: boolean - connect: boolean - config: boolean - }> - > - }> - indexCreate( - indexName: RValue, - indexFunction?: RDatum | Buffer | RDatum[] | ((row: RDatum) => any), - options?: IndexOptions - ): RDatum - indexCreate( - indexName: RValue, - options?: {multi?: boolean; geo?: boolean} - ): RDatum - - indexDrop(indexName: RValue): RDatum - indexList(): RDatum - indexRename( - oldName: RValue, - newName: RValue, - options?: {overwrite: boolean} - ): RDatum - indexStatus(...indexName: string[]): RDatum - indexWait(...indexName: string[]): RDatum - - insert(obj: any, options?: InsertOptions): RDatum> - sync(): RDatum<{synced: number}> - - get(key: any): RSingleSelection - getAll( - key: RValue | RValue | RValue | RValue, - options?: {index: TSchema['index'] | 'id'} - ): RSelection - getAll( - key1: RValue | RValue | RValue | RValue, - key2: RValue | RValue | RValue | RValue, - options?: {index: TSchema['index'] | 'id'} - ): RSelection - getAll( - key1: RValue | RValue | RValue | RValue, - key2: RValue | RValue | RValue | RValue, - key3: RValue | RValue | RValue | RValue, - options?: {index: TSchema['index'] | 'id'} - ): RSelection - getAll( - key1: RValue | RValue | RValue | RValue, - key2: RValue | RValue | RValue | RValue, - key3: RValue | RValue | RValue | RValue, - key4: RValue | RValue | RValue | RValue, - options?: {index: TSchema['index'] | 'id'} - ): RSelection - getAll( - ...params: Array - ): RSelection - - between( - lowKey: any, - highKey: any, - options?: { - index?: string - leftBound?: 'open' | 'closed' - rightBound?: 'open' | 'closed' - } - ): RSelection - getIntersecting(geometry: RDatum, index: {index: TSchema['index'] | 'id'}): RStream - getNearest( - geometry: RDatum, - options?: { - index: TSchema['index'] | 'id' - maxResults?: number - maxDist?: number - unit?: string - geoSystem?: string - } - ): RStream - - config(): RSingleSelection - status(): RDatum - rebalance(): RDatum - reconfigure(options: TableReconfigureOptions): RDatum - wait(options?: WaitOptions): RDatum<{ready: 1}> - getWriteHook(): RDatum<{function: Buffer; query: string}> - setWriteHook( - func: - | null - | Buffer - | (( - context: RDatum<{primary_key: string; timestamp: Date}>, - oldVal: RDatum, - newVal: RDatum - ) => any) - ): RDatum<{function: Buffer; query: string}> -} -export interface RDatabase { - grant( - userName: string, - options?: { - read?: boolean - write?: boolean - connect?: boolean - config?: boolean - } - ): RDatum<{ - granted: number - permissions_changes: Array< - ValueChange<{ - read: boolean - write: boolean - connect: boolean - config: boolean - }> - > - }> - tableCreate(tableName: RValue, options?: TableCreateOptions): RDatum - tableDrop(tableName: RValue): RDatum - tableList(): RDatum<(keyof Schema)[]> - table(tableName: RValue, options?: TableOptions): RTable - - config(): RSingleSelection - rebalance(): RDatum - reconfigure(options?: TableReconfigureOptions): RDatum - wait(options?: WaitOptions): RDatum<{ready: number}> - info(): RDatum<{ - id: string - name: string - type: 'DB' - }> -} - -export interface R { - minval: RValue - maxval: RValue - row: RDatum - monday: RValue - tuesday: RValue - wednesday: RValue - thursday: RValue - friday: RValue - saturday: RValue - sunday: RValue - january: RValue - february: RValue - march: RValue - april: RValue - may: RValue - june: RValue - july: RValue - august: RValue - september: RValue - october: RValue - november: RValue - december: RValue - // Global - connect(options: RConnectionOptions): Promise - connectPool(options?: RPoolConnectionOptions): Promise - getPoolMaster(): MasterPool | undefined - waitForHealthy(): Promise - setNestingLevel(level: number): void - setArrayLimit(limit?: number): void - serialize(query: RQuery): string - deserialize(query: string): T - // send to DB - expr(val: T, nestingLevel?: number): RDatum - (val: T, nestingLevel?: number): RDatum - // indexes - desc(indexName: RValue | Func): any - asc(indexName: RValue | Func): any - // Object creation - // Time - epochTime(epochTime: RValue): RDatum - now(): RDatum - time( - year: RValue, - month: RValue, - day: RValue, - hour: RValue, - minute: RValue, - second: RValue, - timezone: RValue - ): RDatum - time( - year: RValue, - month: RValue, - day: RValue, - timezone: RValue - ): RDatum - ISO8601(time: RValue, options?: {defaultTimezone: string}): RDatum - // Binary - binary(data: any): RDatum - // Object - json(json: RValue): RDatum - // should be (key: string, value: any...) - object(key1: RValue, value1: RValue, ...keyOrValue: RValue[]): RDatum - // Geo - point(longitude: RValue, latitude: RValue): RDatum - line( - point1: [number, number], - point2: [number, number], - ...points: Array<[number, number]> - ): RDatum - line(point1: RDatum, point2: RDatum, ...points: RDatum[]): RDatum - polygon(point1: RDatum, point2: RDatum, point3: RDatum, ...points: RDatum[]): RDatum - polygon( - ll1: [number, number], - ll2: [number, number], - ll3: [number, number], - ...longitudeLatitudes: Array<[number, number]> - ): RDatum - circle( - longitudeLatitude: [number, number] | RDatum, - radius: RValue, - options?: { - numVertices?: number - geoSystem?: 'WGS84' | 'unit_sphere' - unit?: 'm' | 'km' | 'mi' | 'nm' | 'ft' - fill?: boolean - } - ): RDatum - geojson(geoJSON: any): RDatum - // special - args( - arg: Array> | readonly RValue[] - ): any - error(message?: RValue): any - js(js: RValue, options?: {timeout: number}): RDatum - literal(): RDatum - literal(obj: T): RDatum - random( - lowBound?: RValue, - highBound?: RValue | {float: boolean}, - options?: {float: boolean} - ): RDatum - range(startValue: RValue, endValue?: RValue): RStream - uuid(val?: RValue): RDatum - http(url: RValue, options?: HttpRequestOptions): RDatum - http(url: RValue, options?: HTTPStreamRequestOptions): RStream - - // top level permissions - grant( - userName: string, - options: { - read?: boolean - write?: boolean - connect?: boolean - config?: boolean - } - ): RDatum<{ - granted: number - permissions_changes: Array< - ValueChange<{ - read: boolean - write: boolean - connect: boolean - config: boolean - }> - > - }> - // Database management - db(dbName: string): RDatabase - dbCreate(dbName: RValue): RDatum - dbDrop(dbName: RValue): RDatum - dbList(): RDatum - // Table management for default database - table(tableName: RValue, options?: TableOptions): RTable - tableCreate(tableName: RValue, options?: TableCreateOptions): RDatum - tableDrop(tableName: RValue): RDatum - tableList(): RDatum<(keyof Schema)[]> - - // Additional - - // DATABASE / TABLE - config(database: RDatabase): RSingleSelection - config(table: RTable): RSingleSelection - rebalance(database: RDatabase): RDatum - rebalance(table: RTable): RDatum - reconfigure( - database: RDatabase, - options?: TableReconfigureOptions - ): RDatum - reconfigure( - table: RTable, - options: TableReconfigureOptions - ): RDatum - wait(database: RDatabase, options?: WaitOptions): RDatum<{ready: number}> - wait(table: RTable, options?: WaitOptions): RDatum<{ready: 1}> - indexCreate( - table: RTable, - indexName: RValue, - indexFunction?: RDatum | Buffer | RDatum[] | ((row: RDatum) => any), - options?: IndexOptions - ): RDatum - indexCreate( - table: RTable, - indexName: RValue, - options?: {multi: boolean; geo: boolean} - ): RDatum - - indexDrop( - table: RTable, - indexName: RValue - ): RDatum - indexList(table: RTable): RDatum - indexRename( - table: RTable, - oldName: RValue, - newName: RValue, - options?: {overwrite: boolean} - ): RDatum - indexStatus( - table: RTable, - ...indexName: string[] - ): RDatum - indexWait( - table: RTable, - ...indexName: string[] - ): RDatum - - insert( - table: RTable, - obj: any, - options?: InsertOptions - ): RDatum> - sync(table: RTable): RDatum<{synced: number}> - - get(table: RTable, key: any): RSingleSelection - getAll( - table: RTable, - key: any, - options?: {index: Schema[T]['index']} - ): RSelection - getAll( - table: RTable, - key1: any, - key2: any, - options?: {index: Schema[T]['index']} - ): RSelection - getAll( - table: RTable, - key1: any, - key2: any, - key3: any, - options?: {index: Schema[T]['index']} - ): RSelection - getAll( - table: RTable, - key1: any, - key2: any, - key3: any, - key4: any, - options?: {index: Schema[T]['index']} - ): RSelection - - between( - table: RTable, - lowKey: any, - highKey: any, - options?: { - index?: string - leftBound?: 'open' | 'closed' - rightBound?: 'open' | 'closed' - } - ): RSelection - getIntersecting( - table: RTable, - geometry: RDatum, - index: {index: Schema[T]['index']} - ): RStream - getNearest( - table: RTable, - geometry: RDatum, - options?: { - index: Schema[T]['index'] - maxResults?: number - maxDist?: number - unit?: string - geoSystem?: string - } - ): RStream - - status(table: RTable): RDatum - getWriteHook( - table: RTable - ): RDatum<{function: Buffer; query: string}> - setWriteHook( - table: RTable, - func: - | null - | Buffer - | (( - context: RDatum<{primary_key: string; timestamp: Date}>, - oldVal: RDatum, - newVal: RDatum - ) => any) - ): RDatum<{function: Buffer; query: string}> - - // SELECTION / SINGLE SELECTION - update( - selection: RSelection | RSingleSelection, - obj: RValue> | ((arg: RDatum) => any), - options?: UpdateOptions - ): RDatum> - replace( - selection: RSelection | RSingleSelection, - obj: RValue | ((arg: RDatum) => any), - options?: UpdateOptions - ): RDatum> - delete( - selection: RSelection | RSingleSelection, - options?: DeleteOptions - ): RDatum> - changes( - selection: RSingleSelection | RStream, - options?: ChangesOptions - ): RFeed> - - // FEED / STREAM / DATUM - forEach< - T, - U = any, - RES extends - | RDatum> - | RDatum - | RDatum = RDatum> - >( - stream: RStream, - func: (res: RDatum) => RES - ): RES - forEach< - T, - U = any, - ONE = T extends Array ? T1 : never, - RES extends - | RDatum> - | RDatum - | RDatum = RDatum> - >( - datum: RDatum, - func: (res: RDatum) => RES - ): T extends any[] ? RES : never - getField(stream: RStream, fieldName: RValue): RStream - getField(feed: RFeed, fieldName: RValue): RFeed - getField(datum: RDatum, attribute: RValue): RDatum - - innerJoin( - stream: RStream | RValue, - other: RStream | RValue, - predicate: (doc1: RDatum, doc2: RDatum) => RValue - ): RStream> - outerJoin( - stream: RStream | RValue, - other: RStream | RValue, - predicate: (doc1: RDatum, doc2: RDatum) => RValue - ): RStream> // actually left join - eqJoin( - stream: RStream | RValue, - fieldOrPredicate: RValue | Func, - rightTable: RTable, - options?: {index: Schema[U]['index'] | 'id'} - ): RStream> - - zip(stream: RStream): T extends JoinResult ? U1 & U2 : never - - union ? TArr : T>( - stream: RValue | RStream, - ...other: Array | RValue | {interleave: boolean | string}> - ): RStream - union ? TArr : T>( - stream: RValue | RStream | RFeed, - ...other: Array | RValue | RFeed | {interleave: boolean | string}> - ): RFeed - map( - stream: RStream, - ...args: Array, ...args: RDatum[]) => any)> - ): RStream - map( - feed: RFeed, - ...args: Array, ...args: RDatum[]) => any)> - ): RFeed - map ? T1 : never>( - datum: RDatum, - ...args: Array, ...args: RDatum[]) => any)> - ): T extends any[] ? RDatum : never - concatMap( - feed: RFeed, - ...args: Array, ...args: RDatum[]) => any)> - ): RFeed - concatMap( - stream: RStream, - ...args: Array, ...args: RDatum[]) => any)> - ): RStream - concatMap ? T1 : never>( - datum: RDatum, - ...args: Array, ...args: RDatum[]) => any)> - ): T extends any[] ? RDatum : never - withFields(feed: RFeed, ...fields: MultiFieldSelector[]): RFeed> - withFields(stream: RStream, ...fields: MultiFieldSelector[]): RStream> - withFields( - datum: RDatum, - ...fields: MultiFieldSelector[] - ): T extends Array ? RDatum>> : never - hasFields(feed: RFeed, ...fields: MultiFieldSelector[]): RFeed - hasFields(stream: RStream, ...fields: MultiFieldSelector[]): RStream - hasFields( - datum: RDatum, - ...fields: string[] - ): T extends Array ? RDatum : RDatum - filter( - feed: RFeed, - predicate: DeepPartial | ((doc: RDatum) => RValue), - options?: {default: boolean} - ): RFeed - filter( - stream: RStream, - predicate: DeepPartial | ((doc: RDatum) => RValue), - options?: {default: boolean} - ): RStream - filter ? T1 : never>( - datum: RDatum, - predicate: DeepPartial | ((doc: RDatum) => RValue), - options?: {default: boolean} - ): RDatum - includes(datum: RDatum, geometry: RDatum): T extends Array ? RDatum : never - includes(feed: RFeed, geometry: RDatum): RFeed - includes(stream: RStream, geometry: RDatum): RStream - intersects(datum: RDatum, geometry: RDatum): T extends Array ? RDatum : never - intersects(feed: RFeed, geometry: RDatum): RFeed - intersects(stream: RStream, geometry: RDatum): RStream - contains ? T1 : never>( - datum: RDatum, - val1: any[] | null | string | number | object | Func, - ...value: Array> - ): T extends Array ? RDatum : never // also predicate - contains( - stream: RStream, - val1: any[] | null | string | number | object | Func, - ...value: Array> - ): RDatum - orderBy ? T1 : never>( - datum: RDatum, - ...fields: Array> - ): T extends Array ? RDatum : never - orderBy>( - stream: U, - ...fieldOrIndex: Array | {index: string}> - ): U // also r.desc(string) - group< - T, - F extends T extends Array ? keyof T1 : never, - D extends T extends Array ? T2 : never - >( - datum: RDatum, - ...fieldOrFunc: Array> - ): T extends Array ? RDatum : never // >; - group( - stream: RStream, - ...fieldOrFunc: Array) => any) | {index?: string; multi?: boolean}> - ): T extends Array ? RDatum : never // >; - count ? T1 : never>( - datum: RDatum, - value?: RValue | Func - ): T extends Array ? RDatum : never - count(stream: RStream, value?: RValue | Func): RDatum - sum ? T1 : never>( - datum: RDatum, - value?: FieldSelector - ): T extends Array ? RDatum : never - sum(stream: RStream, value?: RValue | Func): RDatum - avg ? T1 : never>( - datum: RValue, - value?: FieldSelector - ): T extends Array ? RDatum : never - avg(stream: RStream, value?: RValue | Func): RDatum - min ? T1 : never>( - datum: RValue, - value?: FieldSelector - ): T extends Array ? RDatum : never - min( - stream: RStream, - value?: RValue | Func | {index: string} - ): RDatum - max ? T1 : never>( - datum: RValue, - value?: FieldSelector - ): T extends Array ? RDatum : never - max( - stream: RStream, - value?: RValue | Func | {index: string} - ): RDatum - reduce ? T1 : never>( - datum: RValue, - reduceFunction: (left: RDatum, right: RDatum) => any - ): T extends Array ? RDatum : never - reduce( - stream: RStream, - reduceFunction: (left: RDatum, right: RDatum) => any - ): RDatum - fold ? T1 : never>( - datum: RValue, - base: any, - foldFunction: (acc: RDatum, next: RDatum) => any, // this any is ACC - options?: { - emit?: ( - acc: RDatum, - next: RDatum, - // tslint:disable-next-line:variable-name - new_acc: RDatum - ) => any[] // this any is RES - finalEmit?: (acc: RStream) => any[] // this any is also RES - } - ): T extends Array ? RDatum : never - fold( - feed: RFeed, - base: any, - foldFunction: (acc: RDatum, next: RDatum) => any, // this any is ACC - options: { - // tslint:disable-next-line:variable-name - emit: (acc: RDatum, next: RDatum, new_acc: RDatum) => any[] // this any is RES - } - ): RFeed - fold( - stream: RStream, - base: any, - foldFunction: (acc: RDatum, next: RDatum) => any, // this any is ACC - options?: { - // tslint:disable-next-line:variable-name - emit?: (acc: RDatum, next: RDatum, new_acc: RDatum) => any[] // this any is RES - finalEmit?: (acc: RStream) => any[] // this any is also RES - } - ): RStream - distinct(datum: RValue): RDatum - distinct(stream: RStream): RStream - distinct(stream: RStream, index: {index: string}): RStream - pluck( - datum: RDatum, - ...fields: MultiFieldSelector[] - ): T extends Array ? RDatum>> : never - pluck(feed: RFeed, ...fields: MultiFieldSelector[]): RFeed> - pluck(stream: RStream, ...fields: MultiFieldSelector[]): RStream> - without( - datum: RDatum, - ...fields: MultiFieldSelector[] - ): T extends Array ? RDatum>> : never - without(feed: RFeed, ...fields: MultiFieldSelector[]): RFeed> - without(stream: RStream, ...fields: MultiFieldSelector[]): RStream> - merge( - obj: object | RDatum, - ...objects: Array any)> - ): RDatum - merge( - stream: RStream, - ...objects: Array any)> - ): RStream - skip(datum: RDatum, n: RValue): RDatum - skip(stream: RStream, n: RValue): RStream - limit(datum: RDatum, n: RValue): RDatum - limit(stream: RStream, n: RValue): RStream - slice( - datum: RDatum, - start: RValue, - end?: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): RDatum - slice( - datum: RDatum, - start: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): RDatum - slice( - stream: RStream, - start: RValue, - end?: RValue, - options?: {leftBound?: 'open' | 'closed'; rightBound?: 'open' | 'closed'} - ): RStream - nth( - datum: RDatum, - attribute: RValue - ): T extends Array ? RDatum : never - nth(stream: RStream, n: RValue): RDatum - nth( - datum: RDatum, - attribute: RValue - ): T extends Array ? RDatum : never - sample(datum: RDatum, n: RValue): T extends Array ? RDatum : never - sample(stream: RStream, n: RValue): RDatum - offsetsOf ? T1 : never>( - datum: RDatum, - single: RValue | Func - ): T extends Array ? RDatum : never - offsetsOf(stream: RStream, single: RValue | Func): RDatum - - isEmpty(datum: RDatum): T extends Array ? RDatum : never - isEmpty(stream: RStream): RDatum - - coerceTo(stream: RStream, type: 'array'): RDatum - coerceTo(stream: RStream, type: 'object'): RDatum - - // DATUM - - coerceTo( - datum: RDatum, - type: 'object' - ): T extends Array ? RDatum : never - coerceTo(datum: RDatum, type: 'string'): RDatum - coerceTo(datum: RDatum, type: 'array'): RDatum - coerceTo(datum: RDatum, type: 'number'): T extends string ? RDatum : never - coerceTo(datum: RDatum, type: 'binary'): T extends string ? RDatum : never - - do( - datum: RValue, - ...args: Array, ...args: RDatum[]) => U)> - ): U extends RStream ? RStream : RDatum - - default(datum: RDatum, value: U): RDatum - // Works only if T is an array - append(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - prepend(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - difference(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - setInsert(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - setUnion(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - setIntersection(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - setDifference(datum: RDatum, value: RValue): T extends U[] ? RDatum : never - insertAt( - datum: RDatum, - index: RValue, - value: RValue - ): T extends U[] ? RDatum : never - changeAt( - datum: RDatum, - index: RValue, - value: RValue - ): T extends U[] ? RDatum : never - spliceAt( - datum: RDatum, - index: RValue, - value: RValue - ): T extends U[] ? RDatum : never - deleteAt( - datum: RDatum, - index: RValue, - value: RValue - ): T extends U[] ? RDatum : never - ungroup(datum: RDatum): RDatum>> - - // Works only if T is a string - - match(datum: RValue, regexp: RValue): RDatum - split( - datum: RValue, - seperator?: RValue, - maxSplits?: RValue - ): RDatum - upcase(datum: RValue): RDatum - downcase(datum: RValue): RDatum - add( - datum: RValue, - ...str: Array | RValue> - ): RDatum - gt( - datum: RValue, - ...value: Array | RValue | RValue> - ): RDatum - ge( - datum: RValue, - ...value: Array | RValue | RValue> - ): RDatum - lt( - datum: RValue, - ...value: Array | RValue | RValue> - ): RDatum - le( - datum: RValue, - ...value: Array | RValue | RValue> - ): RDatum - // Works only for numbers - sub(datum: RValue, ...num: Array>): RDatum - sub(datum: RValue, date: RValue): RDatum - mul(datum: RValue, ...num: Array>): RDatum - div(datum: RValue, ...num: Array>): RDatum - mod(datum: RValue, ...num: Array>): RDatum - - bitAnd(datum: RValue, ...num: Array>): RDatum - bitOr(datum: RValue, ...num: Array>): RDatum - bitXor(datum: RValue, ...num: Array>): RDatum - bitNot(datum: RValue, ...num: Array>): RDatum - bitSal(datum: RValue, ...num: Array>): RDatum - bitShl(datum: RValue, ...num: Array>): RDatum - bitSar(datum: RValue, ...num: Array>): RDatum - bitSht(datum: RValue, ...num: Array>): RDatum - - round(datum: RValue): RDatum - ceil(datum: RValue): RDatum - floor(datum: RValue): RDatum - // Works only for bool - branch( - datum: RValue, - trueBranch: any, - falseBranchOrTest: any, - ...branches: any[] - ): RDatum - and(datum: RValue, ...bool: Array>): RDatum - or(datum: RValue, ...bool: Array>): RDatum - not(datum: RValue): RDatum - // Works only for Date - inTimezone(datum: RValue, timezone: string): RDatum - timezone(datum: RValue): RDatum - during( - datum: RValue, - start: RValue, - end: RValue, - options?: {leftBound: 'open' | 'closed'; rightBound: 'open' | 'closed'} - ): RDatum - date(datum: RValue): RDatum - timeOfDay(datum: RValue): RDatum - year(datum: RValue): RDatum - month(datum: RValue): RDatum - day(datum: RValue): RDatum - dayOfWeek(datum: RValue): RDatum - dayOfYear(datum: RValue): RDatum - hours(datum: RValue): RDatum - minutes(datum: RValue): RDatum - seconds(datum: RValue): RDatum - toISO8601(datum: RValue): RDatum - toEpochTime(datum: RValue): RDatum - // Works only for geo - distance( - datum: RDatum, - geo: RValue, - options?: {geoSystem: string; unit: string} - ): RDatum - toGeojson(datum: RDatum): RDatum - // Works only for line - fill(datum: RDatum): RDatum - polygonSub(datum: RDatum, polygon2: RValue): RDatum - - toJsonString(datum: RDatum): RDatum - toJSON(datum: RDatum): RDatum - - eq(datum: RValue, ...value: RValue[]): RDatum - ne(datum: RValue, ...value: RValue[]): RDatum - - keys(datum: RDatum): RDatum - values(datum: RDatum): RDatum> - - typeOf(query: any): RDatum - info(query: RQuery): RDatum<{ - value?: string - db?: {id: string; name: string; type: string} - doc_count_estimates?: number[] - id?: string - indexes?: string[] - name?: string - primary_key?: string - type: string - }> - info(db: RDatabase): RDatum<{ - id: string - name: string - type: 'DB' - }> -} - -//#endregion operations diff --git a/packages/server/database/types/MeetingMember.ts b/packages/server/database/types/MeetingMember.ts deleted file mode 100644 index 82e8f856c89..00000000000 --- a/packages/server/database/types/MeetingMember.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Can remove this after getting rid of the old RethinkDB migrations -import toTeamMemberId from 'parabol-client/utils/relay/toTeamMemberId' -import {MeetingTypeEnum} from '../../graphql/public/resolverTypes' - -interface MeetingMemberInput { - id?: string - updatedAt?: Date - teamId: string - userId: string - meetingType: MeetingTypeEnum - meetingId: string -} - -export default abstract class MeetingMember { - id: string - meetingType: MeetingTypeEnum - meetingId: string - teamId: string - updatedAt = new Date() - userId: string - constructor(input: MeetingMemberInput) { - const {teamId, meetingType, id, updatedAt, meetingId, userId} = input - this.id = id ?? toTeamMemberId(meetingId, userId) - this.meetingType = meetingType - this.meetingId = meetingId - this.teamId = teamId - this.updatedAt = updatedAt ?? new Date() - this.userId = userId - } -} diff --git a/packages/server/dataloader/RootDataLoader.ts b/packages/server/dataloader/RootDataLoader.ts index 587d3e67826..72e0add8a27 100644 --- a/packages/server/dataloader/RootDataLoader.ts +++ b/packages/server/dataloader/RootDataLoader.ts @@ -36,7 +36,7 @@ export type AllPrimaryLoaders = keyof typeof primaryKeyLoaderMakers export type RegisterDependsOn = (primaryLoaders: AllPrimaryLoaders | AllPrimaryLoaders[]) => void -// The RethinkDB logic is a leaky abstraction! It will be gone soon & this will be generic enough to put in its own package +// TODO move this to its own package interface GenericDataLoader { clearAll(pkLoaderName: TPrimaryLoaderNames | TPrimaryLoaderNames[]): void get( diff --git a/packages/server/dataloader/customRedisQueries.ts b/packages/server/dataloader/customRedisQueries.ts deleted file mode 100644 index ba6123abfef..00000000000 --- a/packages/server/dataloader/customRedisQueries.ts +++ /dev/null @@ -1,55 +0,0 @@ -// Sometimes, a value cached is redis is harder to get than simply querying the primary key on a table -// this allows redis to cache the results of arbitrarily complex rethinkdb queries - -import {sql, SqlBool} from 'kysely' -import ms from 'ms' -import getKysely from '../postgres/getKysely' - -// All results must be mapped to their ids! -const customRedisQueries = { - endTimesByTemplateId: async (templateIds: string[]) => { - if (!templateIds.length) return [] - const pg = getKysely() - const aQuarterAgo = new Date(Date.now() - ms('90d')) - const meetings = await pg - .selectFrom('NewMeeting') - .select('templateId') - .select(({fn}) => [fn.agg('array_agg', ['endedAt']).as('endedAts')]) - .where('templateId', 'in', templateIds) - .where('endedAt', '>=', aQuarterAgo) - .groupBy('templateId') - .limit(1000) - .execute() - - return templateIds.map((id) => { - const group = meetings.find((meeting) => meeting.templateId === id) - return group ? group.endedAts.map((date) => date.getTime()) : [] - }) - }, - publicTemplates: async (meetingTypes: string[]) => { - const pg = getKysely() - const publicTemplatesByType = await Promise.all( - meetingTypes.map((type) => { - const templateType = type === 'poker' ? 'poker' : 'retrospective' - return pg - .selectFrom('MeetingTemplate') - .selectAll() - .where('teamId', '=', 'aGhostTeam') - .where('isActive', '=', true) - .where('type', '=', templateType) - .where(({or, eb}) => - or([ - eb('hideStartingAt', 'is', null), - sql`make_date(2020 , extract(month from current_date)::integer, extract(day from current_date)::integer) between "hideEndingAt" and "hideStartingAt"`, - sql`make_date(2019 , extract(month from current_date)::integer, extract(day from current_date)::integer) between "hideEndingAt" and "hideStartingAt"` - ]) - ) - .execute() - }) - ) - - return publicTemplatesByType - } -} as const - -export default customRedisQueries diff --git a/packages/server/dataloader/rethinkPrimaryKeyLoader.ts b/packages/server/dataloader/rethinkPrimaryKeyLoader.ts deleted file mode 100644 index e6373123a6a..00000000000 --- a/packages/server/dataloader/rethinkPrimaryKeyLoader.ts +++ /dev/null @@ -1,22 +0,0 @@ -import DataLoader from 'dataloader' -import getRethink, {DBType} from '../database/rethinkDriver' -import UpdatableCacheDataLoader from './UpdatableCacheDataLoader' -import normalizeResults from './normalizeResults' - -const rethinkPrimaryKeyLoader = ( - options: DataLoader.Options, - table: T -) => { - // don't pass in a a filter here because they requested a specific ID, they know what they want - const batchFn = async (keys: readonly string[]) => { - const r = await getRethink() - const docs = (await r - .table(table) - .getAll(r.args(keys as string[]), {index: 'id'}) - .run()) as any - return normalizeResults(keys, docs) - } - return new UpdatableCacheDataLoader(batchFn, options) -} - -export default rethinkPrimaryKeyLoader diff --git a/packages/server/eslint.config.mjs b/packages/server/eslint.config.mjs index 80b753f505c..d2a3ed86986 100644 --- a/packages/server/eslint.config.mjs +++ b/packages/server/eslint.config.mjs @@ -17,8 +17,6 @@ export default [ { ignores: [ 'types/webpackEnv.ts', - 'database/migrations', - 'database/stricterR.ts', 'postgres/migrations', '**/generated/', '**/*/githubTypes.ts', @@ -28,7 +26,6 @@ export default [ '**/*/gitlabSchema.graphql', 'graphql/private/schema.graphql', 'graphql/public/schema.graphql', - '**/*/migrationTemplate.ts', '**/*debug.ts', '**/*/pg.d.ts' ] diff --git a/packages/server/graphql/private/mutations/autopauseUsers.ts b/packages/server/graphql/private/mutations/autopauseUsers.ts index f0df40b0375..ba6014a9245 100644 --- a/packages/server/graphql/private/mutations/autopauseUsers.ts +++ b/packages/server/graphql/private/mutations/autopauseUsers.ts @@ -1,7 +1,6 @@ import {InvoiceItemType, Threshold} from 'parabol-client/types/constEnums' import adjustUserCount from '../../../billing/helpers/adjustUserCount' import getKysely from '../../../postgres/getKysely' -import getUserIdsToPause from '../../../postgres/queries/getUserIdsToPause' import {Logger} from '../../../utils/Logger' import {MutationResolvers} from '../resolverTypes' @@ -13,7 +12,13 @@ const autopauseUsers: MutationResolvers['autopauseUsers'] = async ( const pg = getKysely() // RESOLUTION const activeThresh = new Date(Date.now() - Threshold.AUTO_PAUSE) - const userIdsToPause = await getUserIdsToPause(activeThresh) + const usersToPause = await pg + .selectFrom('User') + .select('id') + .where('lastSeenAt', '<=', activeThresh) + .where('inactive', '=', false) + .execute() + const userIdsToPause = usersToPause.map(({id}) => id) const BATCH_SIZE = 100 for (let i = 0; i < 1e5; i++) { diff --git a/packages/server/graphql/private/mutations/checkRethinkPgEquality.ts b/packages/server/graphql/private/mutations/checkRethinkPgEquality.ts deleted file mode 100644 index 03ff9c53399..00000000000 --- a/packages/server/graphql/private/mutations/checkRethinkPgEquality.ts +++ /dev/null @@ -1,105 +0,0 @@ -import getRethink from '../../../database/rethinkDriver' -import getFileStoreManager from '../../../fileStorage/getFileStoreManager' -import {selectNewMeetings} from '../../../postgres/select' -import {checkRowCount, checkTableEq} from '../../../postgres/utils/checkEqBase' -import { - compareDateAlmostEqual, - compareRValStringAsNumber, - compareRValUndefinedAsFalse, - compareRValUndefinedAsNull, - compareRValUndefinedAsNullAndTruncateRVal, - compareRValUndefinedAsZero, - defaultEqFn -} from '../../../postgres/utils/rethinkEqualityFns' -import {MutationResolvers} from '../resolverTypes' - -const handleResult = async ( - tableName: string, - rowCountResult: string, - errors: any[], - writeToFile: boolean | undefined | null -) => { - const result = [rowCountResult, ...errors] - const resultStr = JSON.stringify(result) - if (!writeToFile) return resultStr - - const fileName = `rethinkdbEquality_${tableName}_${new Date().toISOString()}.json` - const manager = getFileStoreManager() - const buffer = Buffer.from(resultStr, 'utf-8') - return manager.putDebugFile(buffer, fileName) -} - -const checkRethinkPgEquality: MutationResolvers['checkRethinkPgEquality'] = async ( - _source, - {tableName, writeToFile, maxErrors} -) => { - const r = await getRethink() - - if (tableName === 'NewMeeting') { - const rowCountResult = await checkRowCount(tableName) - const rethinkQuery = (updatedAt: Date, id: string | number) => { - return r - .table('NewMeeting' as any) - .between([updatedAt, id], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) as any - } - const pgQuery = async (ids: string[]) => { - return selectNewMeetings().where('id', 'in', ids).execute() - } - const errors = await checkTableEq( - rethinkQuery, - pgQuery, - { - id: defaultEqFn, - isLegacy: compareRValUndefinedAsFalse, - createdAt: compareDateAlmostEqual, - updatedAt: compareDateAlmostEqual, - createdBy: defaultEqFn, - endedAt: compareRValUndefinedAsNull, - facilitatorStageId: defaultEqFn, - facilitatorUserId: defaultEqFn, - meetingCount: compareRValUndefinedAsZero, - meetingNumber: compareRValUndefinedAsZero, - name: compareRValUndefinedAsNullAndTruncateRVal(100), - summarySentAt: compareRValUndefinedAsNull, - teamId: defaultEqFn, - meetingType: defaultEqFn, - phases: defaultEqFn, - showConversionModal: compareRValUndefinedAsFalse, - meetingSeriesId: compareRValUndefinedAsNull, - scheduledEndTime: compareRValUndefinedAsNull, - summary: compareRValUndefinedAsNullAndTruncateRVal(10000), - sentimentScore: compareRValUndefinedAsNull, - usedReactjis: compareRValUndefinedAsNull, - slackTs: compareRValStringAsNumber, - engagement: compareRValUndefinedAsNull, - totalVotes: compareRValUndefinedAsNull, - maxVotesPerGroup: compareRValUndefinedAsNull, - disableAnonymity: compareRValUndefinedAsNull, - commentCount: compareRValUndefinedAsNull, - taskCount: compareRValUndefinedAsNull, - agendaItemCount: compareRValUndefinedAsNull, - storyCount: compareRValUndefinedAsNull, - templateId: compareRValUndefinedAsNull, - topicCount: compareRValUndefinedAsNull, - reflectionCount: compareRValUndefinedAsNull, - transcription: compareRValUndefinedAsNull, - recallBotId: compareRValUndefinedAsNull, - videoMeetingURL: compareRValUndefinedAsNull, - autogroupReflectionGroups: compareRValUndefinedAsNull, - resetReflectionGroups: compareRValUndefinedAsNull, - templateRefId: compareRValUndefinedAsNull, - meetingPrompt: compareRValUndefinedAsNull - }, - maxErrors - ) - return handleResult(tableName, rowCountResult, errors, writeToFile) - } - return 'Table not found' -} - -export default checkRethinkPgEquality diff --git a/packages/server/graphql/private/queries/suProOrgInfo.ts b/packages/server/graphql/private/queries/suProOrgInfo.ts index bf400278962..3def46eca5d 100644 --- a/packages/server/graphql/private/queries/suProOrgInfo.ts +++ b/packages/server/graphql/private/queries/suProOrgInfo.ts @@ -11,7 +11,6 @@ const suProOrgInfo: QueryResolvers['suProOrgInfo'] = async (_source, {includeIna const pgResults = await pg .selectFrom('OrganizationUser') .select(['orgId', ({fn}) => fn.count('id').as('orgSize')]) - // use ANY to support case where proOrgIds is empty array. Please use `in` after RethinkDB is gone .where('orgId', 'in', proOrgIds) .where('inactive', '=', false) .where('removedAt', 'is', null) diff --git a/packages/server/graphql/private/typeDefs/Mutation.graphql b/packages/server/graphql/private/typeDefs/Mutation.graphql index cc152270cbf..4eba09faf86 100644 --- a/packages/server/graphql/private/typeDefs/Mutation.graphql +++ b/packages/server/graphql/private/typeDefs/Mutation.graphql @@ -122,30 +122,10 @@ type Mutation { autopauseUsers: Int """ - copies all the records from RethinkDB for a list of organizations + CURRENTLY BROKEN. copies all the records from PG for a list of organizations """ backupOrganization(orgIds: [ID!]!): String! - """ - check equality of a table between rethinkdb and postgres - """ - checkRethinkPgEquality( - """ - The table name to be compared - """ - tableName: String! - - """ - How many errors should be returned - """ - maxErrors: Int - - """ - Whether the output should be written to file - """ - writeToFile: Boolean - ): String! - """ a server-side mutation called when a client connects """ diff --git a/packages/server/graphql/private/typeDefs/PingableServices.graphql b/packages/server/graphql/private/typeDefs/PingableServices.graphql index 8fe88d9e09c..07776b516ac 100644 --- a/packages/server/graphql/private/typeDefs/PingableServices.graphql +++ b/packages/server/graphql/private/typeDefs/PingableServices.graphql @@ -1,9 +1,4 @@ type PingableServices { - """ - Response time for RethinkDB (in milliseconds) -1 if unreachable after 5 seconds - """ - rethinkdb: Int! - """ Response time for Postgres (in milliseconds) -1 if unreachable after 5 seconds """ diff --git a/packages/server/graphql/private/types/PingableServices.ts b/packages/server/graphql/private/types/PingableServices.ts index 8d99475eb97..13c7826157d 100644 --- a/packages/server/graphql/private/types/PingableServices.ts +++ b/packages/server/graphql/private/types/PingableServices.ts @@ -1,5 +1,4 @@ import sleep from 'parabol-client/utils/sleep' -import getRethink from '../../../database/rethinkDriver' import getPg from '../../../postgres/getPg' import getRedis from '../../../utils/getRedis' import {PingableServicesResolvers} from '../resolverTypes' @@ -33,15 +32,6 @@ const PingableServices: PingableServicesResolvers = { } catch { return -1 } - }, - rethinkdb: async () => { - try { - const r = await getRethink() - const duration = await pingService(r(1).run) - return duration - } catch { - return -1 - } } } diff --git a/packages/server/package.json b/packages/server/package.json index 5150c094917..d80bd24fff6 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -61,7 +61,6 @@ "jest-transform-graphql": "^2.1.0", "json-loader": "^0.5.7", "lint-staged": "^10.1.7", - "rethinkdb-ts-migrate": "^0.3.6", "style-loader": "2.0.0", "sucrase": "^3.32.0", "ts-jest": "^29.1.0", @@ -117,7 +116,6 @@ "ms": "^2.0.0", "nest-graphql-endpoint": "0.8.1", "node-env-flag": "0.1.0", - "node-pg-migrate": "^5.9.0", "nodemailer": "^6.9.9", "oauth-1.0a": "^2.2.6", "openai": "^4.53.0", @@ -127,7 +125,6 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "relay-runtime": "^14.1.0", - "rethinkdb-ts": "2.6.0", "rrule-rust": "^2.0.2", "samlify": "^2.8.2", "sanitize-html": "^2.13.0", diff --git a/packages/server/postgres/README.md b/packages/server/postgres/README.md index 303ec662993..03209d500be 100644 --- a/packages/server/postgres/README.md +++ b/packages/server/postgres/README.md @@ -2,20 +2,15 @@ ## Migrations -This folder contains all the postgres migrations that have been run on the database. -If your migration also requires a connection to RethinkDB, you can do that here, too. -The recommended way to write a migration is to call `yarn pg:migrate create NAME` -We no longer use pgm because we want every migration to run independently. -In other words, migration 3 should have a guarantee that migration 2 has already run. PGM doesn't do this. +Migrations are managed by Kysely, and on the CLI by [Kysely-CTL](https://github.com/kysely-org/kysely-ctl). +Kysely-CTL keeps the same API as Knex, so if the docs are not great, you can use the knex migration docs, too. +There are 3 ways migrations are triggered: -## Migrating RethinkDB to PG (Massive Inserts) +- Manually, calling `yarn kysely migrate:latest`, `yarn kysely migrate:up`, or `yarn kysely migrate:down` +- After the app is built, calling `yarn predeploy` (this is run in prod, where the /migrations dir does not exist) +- In dev, calling `yarn dev`, which uses PM2 to call `yarn kysely migrate:latest` -To perform massive inserts, like migrating RethinkDB tables to PG, we use pg-promise, which offers a [simple pattern](https://github.com/vitaly-t/pg-promise/wiki/Data-Imports#massive-inserts). - -Since most tables can't be read into the memory of our NodeJS container, we have to paginate the data. -The easiest way to do that is indexing on `updatedAt` in RethinkDB and paginating on that field. -This is also beneficial because any updates that happen during the migration will end up on the last page. -Note that is requires every write to the RethinkDB table to update the `updatedAt` field! +To create a new migration run `yarn kysely migrate:make NAME` ### Queries diff --git a/packages/server/postgres/getPgp.ts b/packages/server/postgres/getPgp.ts deleted file mode 100644 index 8efb72b1abf..00000000000 --- a/packages/server/postgres/getPgp.ts +++ /dev/null @@ -1,15 +0,0 @@ -import pgpInit, {IDatabase, IMain} from 'pg-promise' -import getPgConfig from './getPgConfig' - -let pgp: IMain | null = null -let pg: IDatabase | null = null - -const getPgp = () => { - if (!pgp || !pg) { - pgp = pgpInit() - pg = pgp(getPgConfig()) - } - return {pg, pgp} -} - -export default getPgp diff --git a/packages/server/postgres/migrationTemplate.ts b/packages/server/postgres/migrationTemplate.ts deleted file mode 100644 index aa37add11bd..00000000000 --- a/packages/server/postgres/migrationTemplate.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(``/* Do good magic */) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(``/* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1611342655964_addOrganizationUserAuditTable.ts b/packages/server/postgres/migrations/1611342655964_addOrganizationUserAuditTable.ts deleted file mode 100644 index 8ae3981588d..00000000000 --- a/packages/server/postgres/migrations/1611342655964_addOrganizationUserAuditTable.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - await pgm.sql(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'OrganizationUserAuditEventTypeEnum') THEN - CREATE TYPE "OrganizationUserAuditEventTypeEnum" AS ENUM ( - 'added', - 'activated', - 'inactivated', - 'removed' - ); - END IF; - CREATE TABLE IF NOT EXISTS "OrganizationUserAudit" ( - id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, - "orgId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "eventDate" TIMESTAMP NOT NULL, - "eventType" "OrganizationUserAuditEventTypeEnum" NOT NULL - ); - CREATE INDEX IF NOT EXISTS "idx_OrganizationUserAudit_orgId" ON "OrganizationUserAudit"("orgId"); - END - $$; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.sql(` - DROP TYPE "OrganizationUserAuditEventTypeEnum" CASCADE; - DROP TABLE "OrganizationUserAudit"; - `) -} diff --git a/packages/server/postgres/migrations/1613005669863_template-refs.ts b/packages/server/postgres/migrations/1613005669863_template-refs.ts deleted file mode 100644 index b96f98bd526..00000000000 --- a/packages/server/postgres/migrations/1613005669863_template-refs.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.noTransaction() - await pgm.sql(` - CREATE TABLE IF NOT EXISTS "TemplateScaleRef" ( - "id" CHAR(24) PRIMARY KEY, - "scale" JSONB NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP - ); - CREATE TABLE IF NOT EXISTS "TemplateRef" ( - "id" CHAR(24) PRIMARY KEY, - "template" JSONB NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP - ); - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.sql(` - DROP TABLE "TemplateScaleRef"; - DROP TABLE "TemplateRef"; - `) -} diff --git a/packages/server/postgres/migrations/1614030642692_refs-for-meetings.ts b/packages/server/postgres/migrations/1614030642692_refs-for-meetings.ts deleted file mode 100644 index 73a4b0d98f1..00000000000 --- a/packages/server/postgres/migrations/1614030642692_refs-for-meetings.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as crypto from 'crypto' -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -import * as _stringify from 'fast-json-stable-stringify' -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -import {Client} from 'pg' -import {RValue, r} from 'rethinkdb-ts' -import {parse} from 'url' -import MeetingPoker from '../../database/types/MeetingPoker' -import {insertTemplateRefQuery, insertTemplateScaleRefQuery} from '../generatedMigrationHelpers' -import getPgConfig from '../getPgConfig' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(): Promise { - const u = parse(process.env.RETHINKDB_URL!) - const config = { - host: u.hostname || '', - port: parseInt(u.port!, 10), - db: u.path!.split('/')[1] - } - await r.connectPool(config) - - const stringify = (_stringify as any).default || _stringify - - const getHashAndJSON = (obj: any) => { - const str = stringify(obj) - const checksum = crypto.createHash('md5') - checksum.update(str) - const id = checksum.digest('base64') - return {id, str} - } - const client = new Client(getPgConfig()) - await client.connect() - - const meetings = (await r - .table('NewMeeting') - .filter({meetingType: 'poker' as any}) - .run()) as unknown as MeetingPoker[] - const templateIds = meetings.map(({templateId}) => templateId) - const uniqueTemplateIds = Array.from(new Set(templateIds)) - const dimensionsByTemplateId = (await r - .table('TemplateDimension') - .getAll(r.args(uniqueTemplateIds), {index: 'templateId'}) - .merge((d: RValue) => ({ - scale: r.table('TemplateScale').get(d('scaleId')) - })) - .orderBy('sortOrder') - .group('templateId') - .ungroup() - .merge((row: RValue) => ({ - name: r.table('MeetingTemplate').get(row('group'))('name'), - id: row('group'), - dimensions: row('reduction') - })) - .run()) as { - id: string - name: string - dimensions: (any & {scale: any})[] - }[] - - const uniqueScaleIdSet = new Set() - const uniqueScales = [] as any[] - dimensionsByTemplateId.forEach((group) => { - const {dimensions} = group - dimensions.forEach((dimension) => { - const {scaleId, scale} = dimension - if (uniqueScaleIdSet.has(scaleId)) return - uniqueScaleIdSet.add(scaleId) - uniqueScales.push(scale) - }) - }) - const templateScales = uniqueScales.map(({name, values}) => { - const scale = {name, values} - const {id, str} = getHashAndJSON(scale) - return {id, scale: str} - }) - - const templateIdToTemplateRefId = {} as Record - const dimensionIdToDimensionRefIdx = {} as Record - - // Handle PG updates - if (templateScales.length) { - await insertTemplateScaleRefQuery.run({templateScales}, client) - } - - await Promise.all( - dimensionsByTemplateId.map((group) => { - const {id, name, dimensions} = group - const templateRef = { - name, - dimensions: dimensions.map((dimension, idx) => { - const {id: dimensionId, name, scaleId} = dimension - // side effects! - dimensionIdToDimensionRefIdx[dimensionId] = idx - - const scaleIdx = uniqueScales.findIndex((scale) => scale.id === scaleId) - const templateScale = templateScales[scaleIdx]! - const {id: scaleRefId} = templateScale - return { - name, - scaleRefId - } - }) - } - const {id: templateRefId, str: templateRefStr} = getHashAndJSON(templateRef) - // side effects! - templateIdToTemplateRefId[id] = templateRefId - const ref = {id: templateRefId, template: templateRefStr} - return insertTemplateRefQuery.run({ref}, client) - }) - ) - - // Handle RethinkDB Updates - // wipe the jira dimension fields since we can no longer use dimensionId - if (await r.tableList().contains('Team').run()) { - await r - .table('Team') - .filter((row: RValue) => row('jiraDimensionFields').default(null).ne(null)) - .update({jiraDimensionFields: []}) - .run() - } - - // add a templateRefId to each meeting - await r(templateIdToTemplateRefId) - .do((lookup: RValue) => { - return r - .table('NewMeeting') - .filter({meetingType: 'poker'}) - .update((meeting: RValue) => ({ - templateRefId: lookup(meeting('templateId')) - })) - }) - .run() - const mapIf = (rArr: any, test: any, f: any) => { - return rArr.map((x: any) => r.branch(test(x), f(x), x)) - } - await r(dimensionIdToDimensionRefIdx) - .do((lookup: any) => { - return r - .table('NewMeeting') - .filter({meetingType: 'poker'}) - .update((meeting: RValue) => ({ - phases: mapIf( - meeting('phases'), - (phase: RValue) => phase('phaseType').eq('ESTIMATE'), - (estimatePhase: RValue) => - estimatePhase.merge({ - stages: estimatePhase('stages').map((stage: any) => - stage.merge({ - dimensionRefIdx: lookup(stage('dimensionId')) - }) - ) - }) - ) - })) - }) - .run() - - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.sql(` - DELETE FROM "TemplateRef"; - DELETE FROM "TemplateScaleRef"; - `) -} diff --git a/packages/server/postgres/migrations/1614361628531_github-auth.ts b/packages/server/postgres/migrations/1614361628531_github-auth.ts deleted file mode 100644 index fb3a8d92bf8..00000000000 --- a/packages/server/postgres/migrations/1614361628531_github-auth.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -import {Client} from 'pg' -import {RValue, r} from 'rethinkdb-ts' -import {parse} from 'url' -import {insertGitHubAuthsQuery} from '../generatedMigrationHelpers' -import getPgConfig from '../getPgConfig' -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(): Promise { - const {hostname: host, port, path} = parse(process.env.RETHINKDB_URL!) - await r.connectPool({ - host: host!, - port: parseInt(port!, 10), - db: path!.split('/')[1] - }) - const client = new Client(getPgConfig()) - await client.connect() - const ghIntegrations = await r - .table('Provider') - .filter({service: 'GitHubIntegration', isActive: true}) - .filter((row: RValue) => row('accessToken').default(null).ne(null)) - .run() - const auths = ghIntegrations.map( - ({accessToken, createdAt, isActive, providerUserName, teamId, updatedAt, userId}) => ({ - accessToken, - createdAt, - updatedAt, - isActive, - login: providerUserName, - teamId, - userId - }) - ) - await client.query(` - CREATE TABLE IF NOT EXISTS "GitHubAuth" ( - "accessToken" VARCHAR(40) NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "isActive" BOOLEAN DEFAULT TRUE NOT NULL, - "login" VARCHAR(200) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - PRIMARY KEY ("userId", "teamId") - ); - `) - if (auths.length) { - await insertGitHubAuthsQuery.run({auths}, client) - } - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(`DROP TABLE "GitHubAuth";`) -} diff --git a/packages/server/postgres/migrations/1616623767058_addUserTable.ts b/packages/server/postgres/migrations/1616623767058_addUserTable.ts deleted file mode 100644 index d1d1ff1249b..00000000000 --- a/packages/server/postgres/migrations/1616623767058_addUserTable.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.noTransaction() - pgm.sql(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TierEnum') THEN - CREATE TYPE "TierEnum" AS ENUM ( - 'personal', - 'pro', - 'enterprise' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'AuthTokenRole') THEN - CREATE TYPE "AuthTokenRole" AS ENUM ( - 'su' - ); - END IF; - CREATE EXTENSION IF NOT EXISTS citext; - CREATE TABLE IF NOT EXISTS "User" ( - id VARCHAR(100) PRIMARY KEY, - email "citext" UNIQUE NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "inactive" BOOLEAN NOT NULL DEFAULT FALSE, - "lastSeenAt" TIMESTAMP WITH TIME ZONE, - "preferredName" VARCHAR(100) NOT NULL, - tier "TierEnum" NOT NULL DEFAULT 'personal', - picture text NOT NULL, - tms VARCHAR(100)[] NOT NULL DEFAULT '{}', - "featureFlags" VARCHAR(50)[] NOT NULL DEFAULT '{}', - identities JSONB[] NOT NULL DEFAULT '{}', - "lastSeenAtURLs" text[], - "segmentId" VARCHAR(100), - "newFeatureId" VARCHAR(100), - "overLimitCopy" VARCHAR(500), - "isRemoved" BOOLEAN NOT NULL DEFAULT FALSE, - "reasonRemoved" VARCHAR(2000), - rol "AuthTokenRole", - "payLaterClickCount" SMALLINT NOT NULL DEFAULT 0 - ); - END - $$; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - pgm.sql(` - DROP TABLE "User"; - DROP TYPE "TierEnum"; - DROP TYPE "AuthTokenRole"; - DROP EXTENSION "citext"; - `) -} diff --git a/packages/server/postgres/migrations/1616623797090_addArrAppendFn.ts b/packages/server/postgres/migrations/1616623797090_addArrAppendFn.ts deleted file mode 100644 index 1857e5911bd..00000000000 --- a/packages/server/postgres/migrations/1616623797090_addArrAppendFn.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.sql(` - CREATE OR REPLACE FUNCTION arr_append_uniq(anyarray, anyelement) - RETURNS anyarray LANGUAGE sql IMMUTABLE AS - 'SELECT CASE WHEN array_position($1, $2) iS NULL THEN $1 || $2 ELSE $1 END;' - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - pgm.sql(` - DROP FUNCTION arr_append_uniq(anyarray, anyelement) - `) -} diff --git a/packages/server/postgres/migrations/1616623804492_addArrDiffFn.ts b/packages/server/postgres/migrations/1616623804492_addArrDiffFn.ts deleted file mode 100644 index 6f30652f511..00000000000 --- a/packages/server/postgres/migrations/1616623804492_addArrDiffFn.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.sql(` - CREATE OR REPLACE FUNCTION arr_diff(arr1 anyarray, arr2 anyarray) - RETURNS anyarray LANGUAGE sql IMMUTABLE AS $$ - SELECT COALESCE(array_agg(el), '{}') - FROM UNNEST(arr1) el - WHERE el != all(arr2) - $$; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - pgm.sql(` - DROP FUNCTION arr_diff(arr1 anyarray, arr2 anyarray) - `) -} diff --git a/packages/server/postgres/migrations/1616623815919_addTeamTable.ts b/packages/server/postgres/migrations/1616623815919_addTeamTable.ts deleted file mode 100644 index b7253400043..00000000000 --- a/packages/server/postgres/migrations/1616623815919_addTeamTable.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.sql(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'MeetingTypeEnum') THEN - CREATE TYPE "MeetingTypeEnum" AS ENUM ( - 'action', - 'retrospective', - 'poker' - ); - END IF; - END - $$; - - CREATE TABLE IF NOT EXISTS "Team" ( - id VARCHAR(100) PRIMARY KEY, - name VARCHAR(100) NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "createdBy" VARCHAR(100), - "isArchived" BOOLEAN NOT NULL DEFAULT FALSE, - "isPaid" BOOLEAN NOT NULL DEFAULT TRUE, - "jiraDimensionFields" JSONB[] NOT NULL DEFAULT '{}', - "lastMeetingType" "MeetingTypeEnum" NOT NULL DEFAULT 'retrospective', - tier "TierEnum" NOT NULL, - "orgId" VARCHAR(100) NOT NULL, - "isOnboardTeam" BOOLEAN NOT NULL DEFAULT FALSE, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() - ); - - CREATE INDEX IF NOT EXISTS "idx_Team_orgId" ON "Team"("orgId"); - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - pgm.sql(` - DROP TABLE "Team"; - DROP TYPE "MeetingTypeEnum"; - `) -} diff --git a/packages/server/postgres/migrations/1616623826693_addArrMergeFn.ts b/packages/server/postgres/migrations/1616623826693_addArrMergeFn.ts deleted file mode 100644 index 676c7d91275..00000000000 --- a/packages/server/postgres/migrations/1616623826693_addArrMergeFn.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.sql(` - CREATE OR REPLACE FUNCTION arr_merge(a1 anyarray, a2 anyarray) - RETURNS anyarray AS $$ - SELECT ARRAY_AGG(a ORDER BY a) FROM ( - SELECT DISTINCT UNNEST($1 || $2) AS a - ) s; - $$ LANGUAGE SQL STRICT; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - pgm.sql(` - DROP FUNCTION arr_merge(a1 anyarray, a2 anyarray) - `) -} diff --git a/packages/server/postgres/migrations/1616623826694_add-github-search-queries.ts b/packages/server/postgres/migrations/1616623826694_add-github-search-queries.ts deleted file mode 100644 index 2580cf9665d..00000000000 --- a/packages/server/postgres/migrations/1616623826694_add-github-search-queries.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - ADD COLUMN IF NOT EXISTS "githubSearchQueries" JSON NOT NULL DEFAULT '{}'; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - DROP COLUMN "githubSearchQueries"; - `) -} diff --git a/packages/server/postgres/migrations/1617206728233_githubSearchQueries.ts b/packages/server/postgres/migrations/1617206728233_githubSearchQueries.ts deleted file mode 100644 index 6c6c423b064..00000000000 --- a/packages/server/postgres/migrations/1617206728233_githubSearchQueries.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - DROP COLUMN "githubSearchQueries"; - `) - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - ADD COLUMN "githubSearchQueries" JSONB[] NOT NULL DEFAULT '{}'; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - DROP COLUMN "githubSearchQueries"; - `) -} diff --git a/packages/server/postgres/migrations/1619383311996_dropUserEmailUniqueConstraint.ts b/packages/server/postgres/migrations/1619383311996_dropUserEmailUniqueConstraint.ts deleted file mode 100644 index 7d778c17b4f..00000000000 --- a/packages/server/postgres/migrations/1619383311996_dropUserEmailUniqueConstraint.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.sql(` - ALTER TABLE "User" - DROP CONSTRAINT IF EXISTS "User_email_key"; - `) -} - -export async function down(): Promise { - // noop -} diff --git a/packages/server/postgres/migrations/1620834940569_lock-team.ts b/packages/server/postgres/migrations/1620834940569_lock-team.ts deleted file mode 100644 index eb9f8c9a9e6..00000000000 --- a/packages/server/postgres/migrations/1620834940569_lock-team.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "Team" - ADD COLUMN "lockMessageHTML" TEXT; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "Team" - DROP COLUMN "lockMessageHTML"; - `) -} diff --git a/packages/server/postgres/migrations/1621283671444_gh-scope.ts b/packages/server/postgres/migrations/1621283671444_gh-scope.ts deleted file mode 100644 index bd8dd5bea3c..00000000000 --- a/packages/server/postgres/migrations/1621283671444_gh-scope.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - ADD COLUMN IF NOT EXISTS "scope" VARCHAR(250); - `) - await pgm.db.query(` - UPDATE "GitHubAuth" - SET "scope" = 'admin:org_hook,read:org,repo,user:email,write:repo_hook' - `) - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - ALTER COLUMN "scope" SET NOT NULL - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "GitHubAuth" - DROP COLUMN "scope"; - `) -} diff --git a/packages/server/postgres/migrations/1622680325173_threads.ts b/packages/server/postgres/migrations/1622680325173_threads.ts deleted file mode 100644 index ba377789302..00000000000 --- a/packages/server/postgres/migrations/1622680325173_threads.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(): Promise { - // use the client here so the next migration runs in serial - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'DiscussionTopicTypeEnum') THEN - CREATE TYPE "DiscussionTopicTypeEnum" AS ENUM ( - 'agendaItem', - 'reflectionGroup', - 'task', - 'githubIssue', - 'jiraIssue' - ); - END IF; - CREATE TABLE IF NOT EXISTS "Discussion" ( - "id" VARCHAR(50) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "meetingId" VARCHAR(100) NOT NULL, - "discussionTopicId" VARCHAR(100) NOT NULL, - "discussionTopicType" "DiscussionTopicTypeEnum" NOT NULL - ); - CREATE INDEX IF NOT EXISTS "idx_Thread_teamId" ON "Discussion"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_Thread_meetingId" ON "Discussion"("meetingId"); - END - $$; - `) - await client.end() -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - DROP TYPE IF EXISTS "DiscussionTopicTypeEnum" CASCADE; - DROP TABLE IF EXISTS "Discussion"; - `) -} diff --git a/packages/server/postgres/migrations/1623102903842_discuss.ts b/packages/server/postgres/migrations/1623102903842_discuss.ts deleted file mode 100644 index 2e663ce7050..00000000000 --- a/packages/server/postgres/migrations/1623102903842_discuss.ts +++ /dev/null @@ -1,219 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -import {Client} from 'pg' -import {RValue, r} from 'rethinkdb-ts' -import AgendaItemsPhase from '../../database/types/AgendaItemsPhase' -import DiscussPhase from '../../database/types/DiscussPhase' -import EstimatePhase from '../../database/types/EstimatePhase' -import generateUID from '../../generateUID' -import {insertDiscussionsQuery} from '../generatedMigrationHelpers' -import getPgConfig from '../getPgConfig' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(): Promise { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) - const client = new Client(getPgConfig()) - await client.connect() - const BATCH_SIZE = 3000 - const MAX_PG_PARAMS = 2 ** 16 - 1 - const DISCUSSION_COLS = 5 - const MAX_INSERT_BATCH_SIZE = MAX_PG_PARAMS / DISCUSSION_COLS - const updateStagesWithDiscussionIds = ( - meetingId: string, - phaseType: string, - discussionIds: string[] - ) => { - return r - .table('NewMeeting') - .get(meetingId) - .update((meeting: RValue) => ({ - phases: meeting('phases').map((phase: RValue) => - r.branch( - phase('phaseType').eq(phaseType), - phase.merge({ - stages: r.map(phase('stages'), r(discussionIds), (stage, discussionId) => - stage.merge({discussionId}) - ) - }), - phase - ) - ) - })) - .run() - } - - const taskServiceToDiscussionTopicType = { - github: 'githubIssue', - jira: 'jiraIssue', - PARABOL: 'task' - } as const - - try { - await r.table('NewMeeting').indexCreate('createdAt').run() - await r.table('NewMeeting').indexWait('createdAt').run() - } catch (e) { - console.log('failed to create new meeting index createdAt') - } - - // update meeting stages with discussionId - for (let i = 0; i < 1e6; i++) { - const skip = i * BATCH_SIZE - console.log('migrating meeting #', skip) - const curMeetings = await r - .table('NewMeeting') - .orderBy('createdAt', {index: 'createdAt'}) - .skip(skip) - .limit(BATCH_SIZE) - .run() - if (curMeetings.length < 1) break - const discussions = [] as any[] - const threadIdToDiscussionId = [] as [string, string][] - const stageUpdates = curMeetings.map((meeting: any) => { - const {id: meetingId, teamId, meetingType, phases} = meeting - if (meetingType === 'retrospective') { - const discussPhase = phases.find( - (phase: any) => phase.phaseType === 'discuss' - ) as DiscussPhase - if (!discussPhase) return - const {stages} = discussPhase - const discussionIds = stages.map(() => generateUID()) - if (stages.length === 1 && !stages[0].reflectionGroupId) return undefined - stages.forEach((stage, idx) => { - const {reflectionGroupId} = stage - if (reflectionGroupId) { - const discussionId = discussionIds[idx]! - threadIdToDiscussionId.push([reflectionGroupId, discussionId]) - discussions.push({ - id: discussionId, - meetingId, - teamId, - discussionTopicId: reflectionGroupId, - discussionTopicType: 'reflectionGroup' as const - }) - } - }) - return updateStagesWithDiscussionIds(meetingId, 'discuss', discussionIds) - } else if (meetingType === 'action') { - const phase = phases.find( - (phase: any) => phase.phaseType === 'agendaitems' - ) as AgendaItemsPhase - if (!phase) return - const {stages} = phase - const discussionIds = stages.map(() => generateUID()) - stages.forEach((stage, idx) => { - const {agendaItemId} = stage - const discussionId = discussionIds[idx]! - threadIdToDiscussionId.push([agendaItemId, discussionId]) - discussions.push({ - id: discussionId, - meetingId, - teamId, - discussionTopicId: agendaItemId, - discussionTopicType: 'agendaItem' as const - }) - }) - return updateStagesWithDiscussionIds(meetingId, 'agendaitems', discussionIds) - } else if (meetingType === 'poker') { - const phase = phases.find((phase: any) => phase.phaseType === 'ESTIMATE') as EstimatePhase - if (!phase) return - const {stages} = phase - const discussionIds = stages.map(() => generateUID()) - stages.forEach((stage, idx) => { - const {service, serviceTaskId} = stage as any - const discussionId = discussionIds[idx]! - threadIdToDiscussionId.push([serviceTaskId, discussionId]) - discussions.push({ - id: discussionId, - meetingId, - teamId, - discussionTopicId: serviceTaskId, - discussionTopicType: - taskServiceToDiscussionTopicType[ - service as keyof typeof taskServiceToDiscussionTopicType - ] || 'task' - }) - }) - return updateStagesWithDiscussionIds(meetingId, 'ESTIMATE', discussionIds) - } - }) - try { - if (discussions.length > 0) { - for (let startIdx = 0; startIdx < discussions.length; startIdx += MAX_INSERT_BATCH_SIZE) { - const batch = discussions.slice(startIdx, startIdx + MAX_INSERT_BATCH_SIZE) - await insertDiscussionsQuery.run({discussions: batch}, client) - } - } - } catch (e) { - console.log('error inserting discussions', e) - throw e - } - try { - await Promise.all(stageUpdates) - } catch (e) { - console.log('error updating stage discussionId', e) - } - - const threadableUpdates = threadIdToDiscussionId.map((item) => { - const [threadId, discussionId] = item - return r({ - comment: r.table('Comment').getAll(threadId, {index: 'threadId'}).update({discussionId}), - task: r.table('Task').getAll(threadId, {index: 'threadId'}).update({discussionId}) - }).run() - }) - - try { - await Promise.all(threadableUpdates) - } catch (e) { - console.log('error updating threadables', e) - } - } - - // update comments with discussionId - try { - await r({ - comment: r.table('Comment').indexCreate('discussionId'), - task: r.table('Task').indexCreate('discussionId') - }).run() - } catch (e) { - // commented out because this is guaranteed to happen if installing from scratch - // console.log('cannot create rethinkdb indexes', e) - } - - try { - await r({ - comment: r.table('Comment').indexWait('discussionId'), - task: r.table('Task').indexWait('discussionId') - }).run() - } catch (e) { - console.log('cannot wait on rethinkdb indexes', e) - } - - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down(pgm: MigrationBuilder): Promise { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) - try { - await Promise.all([ - r.table('Comment').indexDrop('discussionId').run(), - r.table('Task').indexDrop('discussionId').run() - ]) - } catch (e) { - // nope - } - await r.getPoolMaster()?.drain() - await pgm.db.query(` - DELETE FROM "Discussion"; - `) -} diff --git a/packages/server/postgres/migrations/1625576993064_sortJiraDimensionFields.ts b/packages/server/postgres/migrations/1625576993064_sortJiraDimensionFields.ts deleted file mode 100644 index 94c406bd2a5..00000000000 --- a/packages/server/postgres/migrations/1625576993064_sortJiraDimensionFields.ts +++ /dev/null @@ -1,54 +0,0 @@ -//import stringify from 'fast-json-stable-stringify' -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -//import {r} from 'rethinkdb-ts' -//import Team from '../../database/types/Team' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - // With JiraDimensionFieldMap migration, sorting this field is not necessary anymore - /* - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) - - if (await r.tableList().contains('Team').run()) { - const teams = (await r - .table('Team') - .filter(r.row('jiraDimensionFields').default([]).count().gt(0)) - .pluck('id', 'jiraDimensionFields') - .run()) as Pick[] - teams.forEach((team) => { - team.jiraDimensionFields?.sort((a, b) => (stringify(a) < stringify(b) ? -1 : 1)) - }) - await r(teams) - .forEach((team) => { - return r - .table('Team') - .get(team('id')) - .update({ - jiraDimensionFields: team('jiraDimensionFields') - }) - }) - .run() - } - - pgm.sql(` - CREATE OR REPLACE FUNCTION arr_sort (ANYARRAY) - RETURNS ANYARRAY LANGUAGE SQL IMMUTABLE AS - 'SELECT ARRAY(SELECT unnest($1) ORDER BY 1);' - `) - pgm.sql(` - UPDATE "Team" - SET "jiraDimensionFields" = arr_sort("jiraDimensionFields") - WHERE array_length("jiraDimensionFields", 1) > 1; - `) - */ -} - -export async function down(): Promise { - //no op -} diff --git a/packages/server/postgres/migrations/1625576993065_addAtlassianAuthTable.ts b/packages/server/postgres/migrations/1625576993065_addAtlassianAuthTable.ts deleted file mode 100644 index d4e12dfbbbd..00000000000 --- a/packages/server/postgres/migrations/1625576993065_addAtlassianAuthTable.ts +++ /dev/null @@ -1,72 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -import AtlassianManager from 'parabol-client/utils/AtlassianManager' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import {RDatum} from '../../database/stricterR' -import {insertAtlassianAuthsQuery} from '../generatedMigrationHelpers' -import getPgConfig from '../getPgConfig' -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(): Promise { - await connectRethinkDB() - const client = new Client(getPgConfig()) - await client.connect() - - await client.query(` - CREATE TABLE IF NOT EXISTS "AtlassianAuth" ( - "accessToken" VARCHAR(2600) NOT NULL, - "refreshToken" VARCHAR(2600) NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "isActive" BOOLEAN DEFAULT TRUE NOT NULL, - "jiraSearchQueries" JSONB[] NOT NULL DEFAULT '{}', - "cloudIds" VARCHAR(120)[] NOT NULL DEFAULT '{}', - "scope" VARCHAR(240) NOT NULL, - "accountId" VARCHAR(120) NOT NULL, - "teamId" VARCHAR(120) NOT NULL, - "userId" VARCHAR(120) NOT NULL, - PRIMARY KEY ("userId", "teamId") - ); - `) - - const atlassianIntegrations = await r - .table('AtlassianAuth') - .filter((row: RDatum) => row('accessToken').default(null).ne(null)) - .run() - const auths = atlassianIntegrations.map( - ({ - accessToken, - refreshToken, - createdAt, - updatedAt, - isActive, - jiraSearchQueries, - cloudIds, - accountId, - teamId, - userId - }) => ({ - accessToken, - refreshToken, - createdAt, - updatedAt, - isActive, - accountId, - teamId, - userId, - jiraSearchQueries: jiraSearchQueries || [], - cloudIds, - scope: AtlassianManager.SCOPE.join(' ') - }) - ) - if (auths.length) { - await insertAtlassianAuthsQuery.run({auths}, client) - } - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(`DROP TABLE "AtlassianAuth";`) -} diff --git a/packages/server/postgres/migrations/1626296172790_addIsWatched.ts b/packages/server/postgres/migrations/1626296172790_addIsWatched.ts deleted file mode 100644 index e89f3317dcb..00000000000 --- a/packages/server/postgres/migrations/1626296172790_addIsWatched.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "User" - ADD COLUMN IF NOT EXISTS "isWatched" BOOLEAN DEFAULT FALSE NOT NULL -`) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - ALTER TABLE "User" - DROP COLUMN "isWatched"; -`) -} diff --git a/packages/server/postgres/migrations/1626823580960_taskEstimate.ts b/packages/server/postgres/migrations/1626823580960_taskEstimate.ts deleted file mode 100644 index 30de9ebdde3..00000000000 --- a/packages/server/postgres/migrations/1626823580960_taskEstimate.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(pgm: MigrationBuilder): Promise { - pgm.noTransaction() - await pgm.db.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ChangeSourceEnum') THEN - CREATE TYPE "ChangeSourceEnum" AS ENUM ( - 'meeting', - 'task', - 'external' - ); - END IF; - CREATE TABLE IF NOT EXISTS "TaskEstimate" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "changeSource" "ChangeSourceEnum" NOT NULL, - "name" VARCHAR(250) NOT NULL, - "label" VARCHAR(100) NOT NULL, - "taskId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "meetingId" VARCHAR(100), - "stageId" VARCHAR(100), - "discussionId" VARCHAR(100), - "jiraFieldId" VARCHAR(100) - ); - CREATE INDEX IF NOT EXISTS "idx_TaskEstimate_taskId" ON "TaskEstimate"("taskId"); - CREATE INDEX IF NOT EXISTS "idx_TaskEstimate_meetingId" ON "TaskEstimate"("meetingId"); - END - $$; - `) -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - DROP TABLE "TaskEstimate"; - DROP TYPE "ChangeSourceEnum"; - `) -} diff --git a/packages/server/postgres/migrations/1627394777775_addPollsTable.ts b/packages/server/postgres/migrations/1627394777775_addPollsTable.ts deleted file mode 100644 index b941cc3dc41..00000000000 --- a/packages/server/postgres/migrations/1627394777775_addPollsTable.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {ColumnDefinitions, MigrationBuilder} from 'node-pg-migrate' -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export const shorthands: ColumnDefinitions | undefined = undefined - -export async function up(): Promise { - const client = new Client(getPgConfig()) - await client.connect() - - await client.query(` - CREATE TABLE IF NOT EXISTS "Poll" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "deletedAt" TIMESTAMP WITH TIME ZONE DEFAULT NULL, - "endedAt" TIMESTAMP WITH TIME ZONE DEFAULT NULL, - "createdById" VARCHAR(100) NOT NULL REFERENCES "User"("id"), - "discussionId" VARCHAR(100) NOT NULL REFERENCES "Discussion"("id"), - "teamId" VARCHAR(100) NOT NULL REFERENCES "Team"("id"), - "threadSortOrder" DOUBLE PRECISION NOT NULL, - "meetingId" VARCHAR(100), - "title" VARCHAR(300) - ); - CREATE INDEX IF NOT EXISTS "idx_Poll_discussionId" ON "Poll"("discussionId"); - - CREATE TABLE IF NOT EXISTS "PollOption" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "pollId" INT NOT NULL REFERENCES "Poll"("id") ON DELETE CASCADE, - "voteUserIds" VARCHAR(100)[] NOT NULL DEFAULT array[]::VARCHAR[], - "title" VARCHAR(100) - ); - CREATE INDEX IF NOT EXISTS "idx_PollOption_pollId" ON "PollOption"("pollId"); - `) - - await client.end() -} - -export async function down(pgm: MigrationBuilder): Promise { - await pgm.db.query(` - DROP TABLE IF EXISTS "PollOption", "Poll"; - `) -} diff --git a/packages/server/postgres/migrations/1631040185256_uniqueEmail.ts b/packages/server/postgres/migrations/1631040185256_uniqueEmail.ts deleted file mode 100644 index 421ec0aca44..00000000000 --- a/packages/server/postgres/migrations/1631040185256_uniqueEmail.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE UNIQUE INDEX IF NOT EXISTS "idx_User_email" ON "User"("email"); - ALTER TABLE "User" DROP CONSTRAINT IF EXISTS "User_email_key" CASCADE; - DROP INDEX IF EXISTS "User_email_key" CASCADE; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP INDEX IF EXISTS "idx_User_email"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1631553388387_add-template-teams-users.ts b/packages/server/postgres/migrations/1631553388387_add-template-teams-users.ts deleted file mode 100644 index d78210e62d2..00000000000 --- a/packages/server/postgres/migrations/1631553388387_add-template-teams-users.ts +++ /dev/null @@ -1,71 +0,0 @@ -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import {backupTeamQuery, backupUserQuery} from '../generatedMigrationHelpers' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await connectRethinkDB() - const pgGhostTeam = await client.query(`SELECT 1 FROM "Team" WHERE id = 'aGhostTeam';`) - if (pgGhostTeam.rowCount === 0) { - const ghostTeam = (await r.tableList().contains('Team').run()) - ? await r.table('Team').get('aGhostTeam').run() - : { - id: 'aGhostTeam', - name: 'Parabol', - createdAt: new Date('2016-06-01'), - createdBy: 'aGhostUser', - isArchived: false, - isPaid: true, - tier: 'enterprise', - orgId: 'aGhostOrg', - isOnboardTeam: true, - updatedAt: new Date('2016-06-01') - } - const fixedGhostTeam = { - ...ghostTeam, - lastMeetingType: 'retrospective', - updatedAt: new Date(), - jiraDimensionFields: [] - } - await backupTeamQuery.run({teams: [fixedGhostTeam]}, client) - } - - const pgGhostUser = await client.query(`SELECT 1 FROM "User" WHERE id = 'aGhostUser';`) - if (pgGhostUser.rowCount === 0) { - // go from scratch here because it might not always exist in rethinkdb due to now-fixed backupOrganization error - const birth = new Date('Wed Jun 01 2016 00:00:00 GMT+00:00') - const aGhostUser = { - id: 'aGhostUser', - lastSeenAt: birth, - lastSeenAtURLs: [], - preferredName: 'A Ghost', - connectedSockets: [], - email: 'love@parabol.co', - picture: - 'https://action-files.parabol.co/production/build/v5.10.1/42342faa774f05b7626fa91ff8374e59.svg', - createdAt: birth, - tier: 'enterprise', - tms: ['aGhostTeam'], - updatedAt: birth, - inactive: false, - featureFlags: [], - identities: [], - isRemoved: false, - payLaterClickCount: 0 - } as any - await backupUserQuery.run({users: [aGhostUser]}, client) - } - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "Team" WHERE id = 'aGhostTeam';`) - await client.query(`DELETE FROM "User" WHERE id = 'aGhostUser';`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1631822263196_GitHubDimensionFieldMap.ts b/packages/server/postgres/migrations/1631822263196_GitHubDimensionFieldMap.ts deleted file mode 100644 index 2ae2a4fe6f0..00000000000 --- a/packages/server/postgres/migrations/1631822263196_GitHubDimensionFieldMap.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "GitHubDimensionFieldMap" ( - "id" SERIAL, - "teamId" VARCHAR(120) NOT NULL, - "dimensionName" VARCHAR(120) NOT NULL, - "nameWithOwner" VARCHAR(140) NOT NULL, - "labelTemplate" VARCHAR(100) NOT NULL, - PRIMARY KEY ("teamId", "dimensionName", "nameWithOwner") - ); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "GitHubDimensionFieldMap"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1632333793178_addStripeQuantityMismatchLoggingTable.ts b/packages/server/postgres/migrations/1632333793178_addStripeQuantityMismatchLoggingTable.ts deleted file mode 100644 index 859495f7a8a..00000000000 --- a/packages/server/postgres/migrations/1632333793178_addStripeQuantityMismatchLoggingTable.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "StripeQuantityMismatchLogging" ( - "id" SERIAL, - "userId" VARCHAR(120) NOT NULL, - "eventTime" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "eventType" VARCHAR(20) NOT NULL, - "stripePreviousQuantity" INT NOT NULL, - "stripeNextQuantity" INT NOT NULL, - "orgUsers" JSONB[] NOT NULL - ); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "StripeQuantityMismatchLogging"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1632356828133_taskEstimateGitHub.ts b/packages/server/postgres/migrations/1632356828133_taskEstimateGitHub.ts deleted file mode 100644 index dc76de8b222..00000000000 --- a/packages/server/postgres/migrations/1632356828133_taskEstimateGitHub.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TaskEstimate" - ADD COLUMN IF NOT EXISTS "githubLabelName" VARCHAR(50); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TaskEstimate" - DROP COLUMN IF EXISTS "githubLabelName"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1634351004998_addMattermostAuth.ts b/packages/server/postgres/migrations/1634351004998_addMattermostAuth.ts deleted file mode 100644 index d03899f560f..00000000000 --- a/packages/server/postgres/migrations/1634351004998_addMattermostAuth.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "MattermostAuth" ( - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "isActive" BOOLEAN DEFAULT TRUE NOT NULL, - "webhookUrl" VARCHAR(2083) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - PRIMARY KEY ("userId", "teamId") - ); - CREATE INDEX IF NOT EXISTS "idx_MattermostAuth_teamId" ON "MattermostAuth"("teamId"); -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DROP TABLE IF EXISTS "MattermostAuth";`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1638170546562_userDomainField.ts b/packages/server/postgres/migrations/1638170546562_userDomainField.ts deleted file mode 100644 index 86575d0c2bf..00000000000 --- a/packages/server/postgres/migrations/1638170546562_userDomainField.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - ADD COLUMN IF NOT EXISTS "domain" "citext" GENERATED ALWAYS AS (split_part(email, \'@\', 2)) STORED; - CREATE INDEX IF NOT EXISTS "idx_User_domain" ON "User"("domain"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - DROP COLUMN IF EXISTS "domain"; - DROP INDEX IF EXISTS "idx_User_domain"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1638368905980_userUpdatedAtTrigger.ts b/packages/server/postgres/migrations/1638368905980_userUpdatedAtTrigger.ts deleted file mode 100644 index 605c3f1370f..00000000000 --- a/packages/server/postgres/migrations/1638368905980_userUpdatedAtTrigger.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE OR REPLACE FUNCTION "set_updatedAt"() - RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ - BEGIN - NEW."updatedAt" = now(); - RETURN NEW; - END - $$; - DROP TRIGGER IF EXISTS "update_User_updatedAt" ON "User"; - CREATE TRIGGER "update_User_updatedAt" BEFORE UPDATE ON "User" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TRIGGER IF EXISTS "update_User_updatedAt" ON "User"; - DROP FUNCTION IF EXISTS "set_updatedAt"(); - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1639354572171_addIntegrationProviderAndToken.ts b/packages/server/postgres/migrations/1639354572171_addIntegrationProviderAndToken.ts deleted file mode 100644 index 38545db656a..00000000000 --- a/packages/server/postgres/migrations/1639354572171_addIntegrationProviderAndToken.ts +++ /dev/null @@ -1,103 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'IntegrationProviderServiceEnum') THEN - CREATE TYPE "IntegrationProviderServiceEnum" AS ENUM ( - 'gitlab', - 'mattermost' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'IntegrationProviderAuthStrategyEnum') THEN - CREATE TYPE "IntegrationProviderAuthStrategyEnum" AS ENUM ( - 'pat', - 'oauth2', - 'webhook' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'IntegrationProviderScopeEnum') THEN - CREATE TYPE "IntegrationProviderScopeEnum" AS ENUM ( - 'global', - 'org', - 'team' - ); - END IF; - CREATE TABLE IF NOT EXISTS "IntegrationProvider" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "service" "IntegrationProviderServiceEnum" NOT NULL, - "authStrategy" "IntegrationProviderAuthStrategyEnum" NOT NULL, - "scope" "IntegrationProviderScopeEnum" NOT NULL, - "scopeGlobal" BOOLEAN GENERATED ALWAYS AS ( - CASE - WHEN "scope" = 'global' THEN TRUE - ELSE FALSE - END - ) STORED NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "isActive" BOOLEAN DEFAULT TRUE NOT NULL, - "clientId" VARCHAR(255), - "clientSecret" VARCHAR(255), - "serverBaseUrl" VARCHAR(255), - "webhookUrl" VARCHAR(255), - UNIQUE("teamId", "service", "authStrategy"), - CONSTRAINT global_provider_must_be_oauth2 CHECK ( - "scopeGlobal" IS FALSE OR ("scopeGlobal" = TRUE AND "authStrategy" = 'oauth2') - ), - CONSTRAINT "fk_team" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_IntegrationProvider_teamId" ON "IntegrationProvider"("teamId"); - - CREATE TABLE IF NOT EXISTS "TeamMemberIntegrationAuth" ( - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "providerId" INT NOT NULL, - "service" "IntegrationProviderServiceEnum" NOT NULL, - "isActive" BOOLEAN DEFAULT TRUE NOT NULL, - "accessToken" VARCHAR(1028), - "refreshToken" VARCHAR(1028), - "scopes" VARCHAR(255), - PRIMARY KEY ("userId", "teamId", "service"), - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_integrationProvider" - FOREIGN KEY("providerId") - REFERENCES "IntegrationProvider"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TeamMemberIntegrationAuths_teamId" ON "TeamMemberIntegrationAuth"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_TeamMemberIntegrationAuths_providerId" ON "TeamMemberIntegrationAuth"("providerId"); - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "TeamMemberIntegrationAuth" CASCADE; - DROP TABLE IF EXISTS "IntegrationProvider" CASCADE; - DROP TYPE IF EXISTS "IntegrationProviderScopeEnum" CASCADE; - DROP TYPE IF EXISTS "IntegrationProviderAuthStrategyEnum" CASCADE; - DROP TYPE IF EXISTS "IntegrationProviderServiceEnum" CASCADE; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1640229261909_mattermostToIntegrationsTables.ts b/packages/server/postgres/migrations/1640229261909_mattermostToIntegrationsTables.ts deleted file mode 100644 index 8d743e126e2..00000000000 --- a/packages/server/postgres/migrations/1640229261909_mattermostToIntegrationsTables.ts +++ /dev/null @@ -1,65 +0,0 @@ -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' - -interface MattermostAuth { - createdAt: Date - updatedAt: Date - isActive: true - webhookUrl: string - userId: string - teamId: string -} - -export async function up() { - await connectRethinkDB() - const client = new Client(getPgConfig()) - await client.connect() - - const mattermostAuthResults = await client.query( - `SELECT * FROM "MattermostAuth" WHERE "isActive" = TRUE;` - ) - const mattermostAuths = mattermostAuthResults.rows - - const mattermostAuthsToInsert = mattermostAuths.map(async (mattermostAuth) => { - const {teamId, userId, webhookUrl} = mattermostAuth - const result = await client.query<{id: number}>( - ` - INSERT INTO - "IntegrationProvider" ( - "service", - "authStrategy", - "scope", - "webhookUrl", - "teamId" - ) - VALUES($1, $2, $3, $4, $5) - RETURNING id;`, - ['mattermost', 'webhook', 'team', webhookUrl, teamId] - ) - const providerId = result.rows[0]!.id - await client.query( - ` - INSERT INTO - "TeamMemberIntegrationAuth" ( - "providerId", - "teamId", - "userId", - "service" - ) - VALUES($1, $2, $3, $4) - `, - [providerId, teamId, userId, 'mattermost'] - ) - }) - await Promise.all(mattermostAuthsToInsert) - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down() { - // This down function was broken - // To save time, I removed dropping MattermostAuth table from the up migration - // We can drop that table in a later migration -} diff --git a/packages/server/postgres/migrations/1641581237527_addNonNullLastSeenAtConstraint.ts b/packages/server/postgres/migrations/1641581237527_addNonNullLastSeenAtConstraint.ts deleted file mode 100644 index dfec435d687..00000000000 --- a/packages/server/postgres/migrations/1641581237527_addNonNullLastSeenAtConstraint.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - UPDATE "User" SET "lastSeenAt" = "updatedAt" WHERE "lastSeenAt" IS NULL; - ALTER TABLE "User" ALTER COLUMN "lastSeenAt" SET DEFAULT now(); - ALTER TABLE "User" ALTER COLUMN "lastSeenAt" SET NOT NULL; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" ALTER COLUMN "lastSeenAt" DROP DEFAULT; - ALTER TABLE "User" ALTER COLUMN "lastSeenAt" DROP NOT NULL; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1642094555266_addJiraServerIntegrationProvider.ts b/packages/server/postgres/migrations/1642094555266_addJiraServerIntegrationProvider.ts deleted file mode 100644 index cf5a4443a26..00000000000 --- a/packages/server/postgres/migrations/1642094555266_addJiraServerIntegrationProvider.ts +++ /dev/null @@ -1,61 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TYPE "IntegrationProviderServiceEnum" ADD VALUE IF NOT EXISTS 'jiraServer'; - ALTER TYPE "IntegrationProviderAuthStrategyEnum" ADD VALUE IF NOT EXISTS 'oauth1'; - ALTER TABLE "IntegrationProvider" - ADD COLUMN IF NOT EXISTS "consumerKey" VARCHAR(255), - ADD COLUMN IF NOT EXISTS "consumerSecret" TEXT; - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - DROP COLUMN IF EXISTS "consumerKey", - DROP COLUMN IF EXISTS "consumerSecret", - DROP CONSTRAINT global_provider_must_be_oauth2; - - DELETE FROM "IntegrationProvider" WHERE "service" = 'jiraServer' OR "authStrategy" = 'oauth1'; - - ALTER TYPE "IntegrationProviderServiceEnum" RENAME TO "IntegrationProviderServiceEnum_delete"; - ALTER TYPE "IntegrationProviderAuthStrategyEnum" RENAME TO "IntegrationProviderAuthStrategyEnumA_delete"; - - CREATE TYPE "IntegrationProviderServiceEnum" AS ENUM ( - 'gitlab', - 'mattermost' - ); - CREATE TYPE "IntegrationProviderAuthStrategyEnum" AS ENUM ( - 'pat', - 'oauth2', - 'webhook' - ); - - ALTER TABLE "IntegrationProvider" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum", - ALTER COLUMN "authStrategy" TYPE "IntegrationProviderAuthStrategyEnum" USING "authStrategy"::text::"IntegrationProviderAuthStrategyEnum", - ADD CONSTRAINT global_provider_must_be_oauth2 CHECK ( - "scopeGlobal" IS FALSE OR ("scopeGlobal" = TRUE AND "authStrategy" = 'oauth2') - ); - - ALTER TABLE "TeamMemberIntegrationAuth" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum"; - - DROP TYPE "IntegrationProviderServiceEnum_delete"; - DROP TYPE "IntegrationProviderAuthStrategyEnumA_delete"; - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1643101068628_addOAuth1TeamMemberIntegrationAuth.ts b/packages/server/postgres/migrations/1643101068628_addOAuth1TeamMemberIntegrationAuth.ts deleted file mode 100644 index 603a5f52683..00000000000 --- a/packages/server/postgres/migrations/1643101068628_addOAuth1TeamMemberIntegrationAuth.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TeamMemberIntegrationAuth" - ADD COLUMN IF NOT EXISTS "accessTokenSecret" TEXT; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TeamMemberIntegrationAuth" - DROP COLUMN IF EXISTS "accessTokenSecret"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1644936872423_addTeamPromptResponseTable.ts b/packages/server/postgres/migrations/1644936872423_addTeamPromptResponseTable.ts deleted file mode 100644 index 9f9b72bf372..00000000000 --- a/packages/server/postgres/migrations/1644936872423_addTeamPromptResponseTable.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'Reactji') THEN - CREATE TYPE "Reactji" AS (shortName text, userId text); - END IF; - - ALTER TYPE "DiscussionTopicTypeEnum" ADD VALUE IF NOT EXISTS 'teamPromptResponse'; - - ALTER TYPE "MeetingTypeEnum" ADD VALUE IF NOT EXISTS 'teamPrompt'; - - CREATE TABLE IF NOT EXISTS "TeamPromptResponse" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "meetingId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "sortOrder" INT NOT NULL, - "content" JSONB NOT NULL, - "plaintextContent" TEXT NOT NULL, - "reactjis" "Reactji"[] NOT NULL DEFAULT array[]::"Reactji"[], - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - - CREATE INDEX IF NOT EXISTS "idx_TeamPromptResponse_meetingId" ON "TeamPromptResponse"("meetingId"); - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TYPE "DiscussionTopicTypeEnum" RENAME TO "DiscussionTopicTypeEnum_delete"; - CREATE TYPE "DiscussionTopicTypeEnum" AS ENUM ( - 'agendaItem', - 'reflectionGroup', - 'task', - 'githubIssue', - 'jiraIssue' - ); - ALTER TABLE "Discussion" - ALTER COLUMN "discussionTopicType" TYPE "DiscussionTopicTypeEnum" USING "discussionTopicType"::text::"DiscussionTopicTypeEnum"; - DROP TYPE "DiscussionTopicTypeEnum_delete"; - - ALTER TYPE "MeetingTypeEnum" RENAME TO "MeetingTypeEnum_delete"; - CREATE TYPE "MeetingTypeEnum" AS ENUM ( - 'action', - 'retrospective', - 'poker' - ); - ALTER TABLE "Team" - ALTER COLUMN "lastMeetingType" DROP DEFAULT, - ALTER COLUMN "lastMeetingType" TYPE "MeetingTypeEnum" USING "lastMeetingType"::text::"MeetingTypeEnum", - ALTER COLUMN "lastMeetingType" SET DEFAULT 'retrospective'; - DROP TYPE "MeetingTypeEnum_delete"; - - DROP TABLE IF EXISTS "TeamPromptResponse"; - - DROP TYPE IF EXISTS "Reactji"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1647259140753_dropMattermostAuthTable.ts b/packages/server/postgres/migrations/1647259140753_dropMattermostAuthTable.ts deleted file mode 100644 index 785d95964f7..00000000000 --- a/packages/server/postgres/migrations/1647259140753_dropMattermostAuthTable.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "MattermostAuth"; - `) - await client.end() -} - -export async function down() { - // No undo magic, table was migrated some time ago in https://github.com/ParabolInc/parabol/pull/5829 -} diff --git a/packages/server/postgres/migrations/1648135135375_addAzureDevOpsIntegrationProvider.ts b/packages/server/postgres/migrations/1648135135375_addAzureDevOpsIntegrationProvider.ts deleted file mode 100644 index 86b6f591169..00000000000 --- a/packages/server/postgres/migrations/1648135135375_addAzureDevOpsIntegrationProvider.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TYPE "IntegrationProviderServiceEnum" ADD VALUE IF NOT EXISTS 'azureDevOps'; - - ALTER TABLE "IntegrationProvider" - ADD COLUMN IF NOT EXISTS "tenantId" VARCHAR(255); - - AlTER TABLE "TeamMemberIntegrationAuth" - ALTER COLUMN "accessToken" TYPE VARCHAR(2056), - ALTER COLUMN "refreshToken" TYPE VARCHAR(2056); - - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - DROP COLUMN IF EXISTS "tenantId"; - - DELETE FROM "IntegrationProvider" WHERE "service" = 'azureDevOps'; - - ALTER TYPE "IntegrationProviderServiceEnum" RENAME TO "IntegrationProviderServiceEnum_delete"; - - CREATE TYPE "IntegrationProviderServiceEnum" AS ENUM ( - 'gitlab', - 'mattermost', - 'jiraServer' - ); - - ALTER TABLE "IntegrationProvider" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum"; - - ALTER TABLE "TeamMemberIntegrationAuth" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum", - ALTER COLUMN "accessToken" TYPE VARCHAR(1028), - ALTER COLUMN "refreshToken" TYPE VARCHAR(1028); - - DROP TYPE "IntegrationProviderServiceEnum_delete"; - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1649750150687_GitLabDimensionFieldMap.ts b/packages/server/postgres/migrations/1649750150687_GitLabDimensionFieldMap.ts deleted file mode 100644 index 0d49ea217c0..00000000000 --- a/packages/server/postgres/migrations/1649750150687_GitLabDimensionFieldMap.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "GitLabDimensionFieldMap" ( - "id" SERIAL UNIQUE, - "teamId" VARCHAR(100) NOT NULL, - "dimensionName" VARCHAR(120) NOT NULL, - "projectId" INT NOT NULL, - "providerId" INT NOT NULL, - "labelTemplate" VARCHAR(100) NOT NULL, - PRIMARY KEY ("teamId", "dimensionName", "projectId", "providerId") - ); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "GitLabDimensionFieldMap"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1650027588544_addMeetingUserIdUniqueConstraintsToTeamPromptResponseTable.ts b/packages/server/postgres/migrations/1650027588544_addMeetingUserIdUniqueConstraintsToTeamPromptResponseTable.ts deleted file mode 100644 index 95283d46a30..00000000000 --- a/packages/server/postgres/migrations/1650027588544_addMeetingUserIdUniqueConstraintsToTeamPromptResponseTable.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TeamPromptResponse" DROP CONSTRAINT IF EXISTS "TeamPromptResponse_meetingIdUserId_unique"; - ALTER TABLE "TeamPromptResponse" ADD CONSTRAINT "TeamPromptResponse_meetingIdUserId_unique" UNIQUE ("meetingId", "userId"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TeamPromptResponse" DROP CONSTRAINT IF EXISTS "TeamPromptResponse_meetingIdUserId_unique"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1650768593875_add-AzureDevOpsDimensionFieldMap.ts b/packages/server/postgres/migrations/1650768593875_add-AzureDevOpsDimensionFieldMap.ts deleted file mode 100644 index ed091e055c8..00000000000 --- a/packages/server/postgres/migrations/1650768593875_add-AzureDevOpsDimensionFieldMap.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "AzureDevOpsDimensionFieldMap" ( - "id" SERIAL UNIQUE, - "teamId" VARCHAR(120) NOT NULL, - "dimensionName" VARCHAR(120) NOT NULL, - "fieldName" VARCHAR(140) NOT NULL, - "fieldId" VARCHAR(100) NOT NULL, - "instanceId" VARCHAR(100) NOT NULL, - "fieldType" VARCHAR(100) NOT NULL, - "projectKey" VARCHAR(100) NOT NULL, - PRIMARY KEY ("teamId", "dimensionName", "instanceId", "projectKey") - ); - `) - await client.end() -} -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "AzureDevOpsDimensionFieldMap"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1650935732791_taskEstimateAzureDevOps.ts b/packages/server/postgres/migrations/1650935732791_taskEstimateAzureDevOps.ts deleted file mode 100644 index a9334dff5ad..00000000000 --- a/packages/server/postgres/migrations/1650935732791_taskEstimateAzureDevOps.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TaskEstimate" - ADD COLUMN IF NOT EXISTS "azureDevOpsFieldName" VARCHAR(50); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TaskEstimate" - DROP COLUMN IF EXISTS "azureDevOpsFieldName"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1651778831990_addMSTeamsIntegrationProvider.ts b/packages/server/postgres/migrations/1651778831990_addMSTeamsIntegrationProvider.ts deleted file mode 100644 index 0ed13eb2bb4..00000000000 --- a/packages/server/postgres/migrations/1651778831990_addMSTeamsIntegrationProvider.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TYPE "IntegrationProviderServiceEnum" ADD VALUE IF NOT EXISTS 'msTeams'; - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - DELETE FROM "IntegrationProvider" WHERE "service" = 'msTeams'; - ALTER TYPE "IntegrationProviderServiceEnum" RENAME TO "IntegrationProviderServiceEnum_delete"; - CREATE TYPE "IntegrationProviderServiceEnum" AS ENUM ( - 'gitlab', - 'mattermost', - 'jiraServer', - 'azureDevOps' - ); - ALTER TABLE "IntegrationProvider" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum"; - ALTER TABLE "TeamMemberIntegrationAuth" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum", - DROP TYPE "IntegrationProviderServiceEnum_delete"; - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1652081624156_addJiraServerDimensionFieldMap.ts b/packages/server/postgres/migrations/1652081624156_addJiraServerDimensionFieldMap.ts deleted file mode 100644 index 1e198140026..00000000000 --- a/packages/server/postgres/migrations/1652081624156_addJiraServerDimensionFieldMap.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "JiraServerDimensionFieldMap" ( - "id" SERIAL UNIQUE, - "providerId" INTEGER NOT NULL, - "teamId" VARCHAR(120) NOT NULL, - "dimensionName" VARCHAR(120) NOT NULL, - "projectId" VARCHAR(120) NOT NULL, - "issueType" VARCHAR(120) NOT NULL, - "fieldId" VARCHAR(120) NOT NULL, - "fieldName" VARCHAR(120) NOT NULL, - "fieldType" VARCHAR(120) NOT NULL, - PRIMARY KEY ("providerId", "teamId", "projectId", "issueType", "dimensionName") - ); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "JiraServerDimensionFieldMap"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1652361575188_addUpdatedAtTrigger.ts b/packages/server/postgres/migrations/1652361575188_addUpdatedAtTrigger.ts deleted file mode 100644 index 278339d1077..00000000000 --- a/packages/server/postgres/migrations/1652361575188_addUpdatedAtTrigger.ts +++ /dev/null @@ -1,56 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TRIGGER IF EXISTS "update_Team_updatedAt" ON "Team"; - CREATE TRIGGER "update_Team_updatedAt" BEFORE UPDATE ON "Team" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_AtlassianAuth_updatedAt" ON "AtlassianAuth"; - CREATE TRIGGER "update_AtlassianAuth_updatedAt" BEFORE UPDATE ON "AtlassianAuth" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_TeamMemberIntegrationAuth_updatedAt" ON "TeamMemberIntegrationAuth"; - CREATE TRIGGER "update_TeamMemberIntegrationAuth_updatedAt" BEFORE UPDATE ON "TeamMemberIntegrationAuth" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_IntegrationProvider_updatedAt" ON "IntegrationProvider"; - CREATE TRIGGER "update_IntegrationProvider_updatedAt" BEFORE UPDATE ON "IntegrationProvider" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_GitHubAuth_updatedAt" ON "GitHubAuth"; - CREATE TRIGGER "update_GitHubAuth_updatedAt" BEFORE UPDATE ON "GitHubAuth" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_Poll_updatedAt" ON "Poll"; - CREATE TRIGGER "update_Poll_updatedAt" BEFORE UPDATE ON "Poll" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_PollOption_updatedAt" ON "PollOption"; - CREATE TRIGGER "update_PollOption_updatedAt" BEFORE UPDATE ON "PollOption" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - DROP TRIGGER IF EXISTS "update_TeamPromptResponse_updatedAt" ON "TeamPromptResponse"; - CREATE TRIGGER "update_TeamPromptResponse_updatedAt" BEFORE UPDATE ON "TeamPromptResponse" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TRIGGER IF EXISTS "update_Team_updatedAt" ON "Team"; - - DROP TRIGGER IF EXISTS "update_AtlassianAuth_updatedAt" ON "AtlassianAuth"; - - DROP TRIGGER IF EXISTS "update_TeamMemberIntegrationAuth_updatedAt" ON "TeamMemberIntegrationAuth"; - - DROP TRIGGER IF EXISTS "update_IntegrationProvider_updatedAt" ON "IntegrationProvider"; - - DROP TRIGGER IF EXISTS "update_GitHubAuth_updatedAt" ON "GitHubAuth"; - - DROP TRIGGER IF EXISTS "update_Poll_updatedAt" ON "Poll"; - - DROP TRIGGER IF EXISTS "update_PollOption_updatedAt" ON "PollOption"; - - DROP TRIGGER IF EXISTS "update_TeamPromptResponse_updatedAt" ON "TeamPromptResponse"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1653315561723_addExpiresAtToTeamMemberIntegrationAuth.ts b/packages/server/postgres/migrations/1653315561723_addExpiresAtToTeamMemberIntegrationAuth.ts deleted file mode 100644 index c58c238c361..00000000000 --- a/packages/server/postgres/migrations/1653315561723_addExpiresAtToTeamMemberIntegrationAuth.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TeamMemberIntegrationAuth" - ADD COLUMN IF NOT EXISTS "expiresAt" TIMESTAMP WITH TIME ZONE DEFAULT NULL; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "TeamMemberIntegrationAuth" - DROP COLUMN IF EXISTS "expiresAt"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1654861495447_addIntegrationSearchQuery.ts b/packages/server/postgres/migrations/1654861495447_addIntegrationSearchQuery.ts deleted file mode 100644 index 1912a665df7..00000000000 --- a/packages/server/postgres/migrations/1654861495447_addIntegrationSearchQuery.ts +++ /dev/null @@ -1,50 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "IntegrationSearchQuery" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "userId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "providerId" INT, - "service" "IntegrationProviderServiceEnum" NOT NULL, - "query" JSONB NOT NULL DEFAULT '{}', - "lastUsedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - CONSTRAINT "fk_integrationProvider" - FOREIGN KEY("providerId") - REFERENCES "IntegrationProvider"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - - CREATE UNIQUE INDEX IF NOT EXISTS integration_search_query_unique_not_null - ON "IntegrationSearchQuery" ("userId", "teamId", "service", "query", "providerId") - WHERE "providerId" IS NOT NULL; - - CREATE UNIQUE INDEX IF NOT EXISTS integration_search_query_unique_null - ON "IntegrationSearchQuery" ("userId", "teamId", "service", "query") - WHERE "providerId" IS NULL; - - DROP TRIGGER IF EXISTS "update_IntegrationSearchQuery_updatedAt" ON "IntegrationSearchQuery"; - CREATE TRIGGER "update_IntegrationSearchQuery_updatedAt" BEFORE UPDATE ON "IntegrationSearchQuery" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TRIGGER IF EXISTS "update_IntegrationSearchQuery_updatedAt" ON "IntegrationSearchQuery"; - DROP TABLE IF EXISTS "IntegrationSearchQuery"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1654861495448_OrganizationApprovedDomains.ts b/packages/server/postgres/migrations/1654861495448_OrganizationApprovedDomains.ts deleted file mode 100644 index 02113f7f65c..00000000000 --- a/packages/server/postgres/migrations/1654861495448_OrganizationApprovedDomains.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "OrganizationApprovedDomain" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "removedAt" TIMESTAMP WITH TIME ZONE, - "domain" VARCHAR(255) CHECK (lower(domain) = domain) NOT NULL, - "orgId" VARCHAR(100) NOT NULL, - "addedByUserId" VARCHAR(100) NOT NULL, - CONSTRAINT "fk_addedByUserId" - FOREIGN KEY("addedByUserId") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - CREATE UNIQUE INDEX IF NOT EXISTS "idx_OrganizationApprovedDomain_orgId_domain" - --Guaurantee only 1 null per composite - ON "OrganizationApprovedDomain"("orgId", "domain", ("removedAt" IS NULL)) - WHERE "removedAt" IS NULL; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "OrganizationApprovedDomain" CASCADE; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1654861495449_domainIndex.ts b/packages/server/postgres/migrations/1654861495449_domainIndex.ts deleted file mode 100644 index 5eb12d20a2c..00000000000 --- a/packages/server/postgres/migrations/1654861495449_domainIndex.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE INDEX IF NOT EXISTS "idx_OrganizationApprovedDomain_domain" ON "OrganizationApprovedDomain"("domain");`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP INDEX IF EXISTS "idx_OrganizationApprovedDomain_domain" ON "OrganizationApprovedDomain"("domain");`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1654861495450_migrateSecureDomain.ts b/packages/server/postgres/migrations/1654861495450_migrateSecureDomain.ts deleted file mode 100644 index a22e396cd5e..00000000000 --- a/packages/server/postgres/migrations/1654861495450_migrateSecureDomain.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const client = new Client(getPgConfig()) - await client.connect() - const securedDomains = (await r.table('SecureDomain').coerceTo('array').run()) as { - id: string - domain: string - }[] - try { - await Promise.all( - securedDomains.map((sd) => { - return client.query( - ` - INSERT INTO "OrganizationApprovedDomain" ("domain", "orgId", "addedByUserId") - VALUES($1, $2, $3)`, - [sd.domain.trim().toLowerCase(), 'aGhostOrg', 'aGhostUser'] - ) - }) - ) - } catch { - // already exists - } - await client.end() - await r.getPoolMaster()?.drain() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DELETE FROM "OrganizationApprovedDomain" - WHERE "userId" = "aGhostUser";`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1656389795923_addAzureDevOpsDimensionFieldMapWorkItemType.ts b/packages/server/postgres/migrations/1656389795923_addAzureDevOpsDimensionFieldMapWorkItemType.ts deleted file mode 100644 index f9b8f7c7e95..00000000000 --- a/packages/server/postgres/migrations/1656389795923_addAzureDevOpsDimensionFieldMapWorkItemType.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - // original query that ran did not have quotes on the pkey constraint, so i added them to get around duplicate pkey error - await client.query(` - ALTER TABLE "AzureDevOpsDimensionFieldMap" - ADD COLUMN IF NOT EXISTS "workItemType" VARCHAR(255) NOT NULL; - - ALTER TABLE "AzureDevOpsDimensionFieldMap" - DROP CONSTRAINT IF EXISTS "AzureDevOpsDimensionFieldMap_pkey"; - - ALTER TABLE "AzureDevOpsDimensionFieldMap" - ADD CONSTRAINT "AzureDevOpsDimensionFieldMap_pkey" PRIMARY KEY ("teamId", "dimensionName", "instanceId", "projectKey", "workItemType"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "AzureDevOpsDimensionFieldMap" - DROP CONSTRAINT IF EXISTS "AzureDevOpsDimensionFieldMap_pkey"; - - ALTER TABLE "AzureDevOpsDimensionFieldMap" - ADD CONSTRAINT "AzureDevOpsDimensionFieldMap_pkey" PRIMARY KEY ("teamId", "dimensionName", "instanceId", "projectKey"); - - ALTER TABLE "AzureDevOpsDimensionFieldMap" - DROP COLUMN IF EXISTS "workItemType"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1658834062488_createMeetingSeries.ts b/packages/server/postgres/migrations/1658834062488_createMeetingSeries.ts deleted file mode 100644 index 9b0e5305759..00000000000 --- a/packages/server/postgres/migrations/1658834062488_createMeetingSeries.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "MeetingSeries" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "meetingType" "MeetingTypeEnum" NOT NULL, - "title" VARCHAR(255) NOT NULL, - "recurrenceRule" VARCHAR(255) NOT NULL, - "duration" INT NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "cancelledAt" TIMESTAMP WITH TIME ZONE - ); - - DROP TRIGGER IF EXISTS "update_MeetingSeries_updatedAt" ON "MeetingSeries"; - CREATE TRIGGER "update_MeetingSeries_updatedAt" BEFORE UPDATE ON "MeetingSeries" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "MeetingSeries"; - DROP TRIGGER IF EXISTS "update_MeetingSeries_updatedAt" ON "MeetingSeries"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1659973034251_alterMeetingSeries.ts b/packages/server/postgres/migrations/1659973034251_alterMeetingSeries.ts deleted file mode 100644 index 2ae0c8563bf..00000000000 --- a/packages/server/postgres/migrations/1659973034251_alterMeetingSeries.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "MeetingSeries" - DROP CONSTRAINT IF EXISTS "fk_teamId"; - - ALTER TABLE "MeetingSeries" - DROP CONSTRAINT IF EXISTS "fk_facilitatorId"; - - ALTER TABLE "MeetingSeries" - ADD COLUMN IF NOT EXISTS "teamId" VARCHAR(100) NOT NULL, - ADD COLUMN IF NOT EXISTS "facilitatorId" VARCHAR(100) NOT NULL, - ADD CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - ADD CONSTRAINT "fk_facilitatorId" - FOREIGN KEY("facilitatorId") - REFERENCES "User"("id") ON DELETE CASCADE; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "MeetingSeries" - DROP COLUMN IF EXISTS "teamId", - DROP COLUMN IF EXISTS "facilitatorId", - DROP CONSTRAINT IF EXISTS "fk_teamId", - DROP CONSTRAINT IF EXISTS "fk_facilitatorId"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1663254566765_addSendSummaryEmailToUser.ts b/packages/server/postgres/migrations/1663254566765_addSendSummaryEmailToUser.ts deleted file mode 100644 index 95a075635ea..00000000000 --- a/packages/server/postgres/migrations/1663254566765_addSendSummaryEmailToUser.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - ADD COLUMN IF NOT EXISTS "sendSummaryEmail" BOOLEAN DEFAULT TRUE NOT NULL -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - DROP COLUMN "sendSummaryEmail"; -`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1663850062796_JiraDimensionFieldMap.ts b/packages/server/postgres/migrations/1663850062796_JiraDimensionFieldMap.ts deleted file mode 100644 index 7b5a85abb92..00000000000 --- a/packages/server/postgres/migrations/1663850062796_JiraDimensionFieldMap.ts +++ /dev/null @@ -1,60 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "JiraDimensionFieldMap" ( - "id" SERIAL, - "teamId" VARCHAR(120) NOT NULL, - "cloudId" VARCHAR(120) NOT NULL, - "projectKey" VARCHAR(120) NOT NULL, - "issueType" VARCHAR(120) NOT NULL, - "dimensionName" VARCHAR(120) NOT NULL, - "fieldId" VARCHAR(120) NOT NULL, - "fieldName" VARCHAR(120) NOT NULL, - "fieldType" VARCHAR(120) NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - PRIMARY KEY ("teamId", "cloudId", "projectKey", "issueType", "dimensionName") - ); - DROP TRIGGER IF EXISTS "update_JiraDimensionFieldMap_updatedAt" ON "JiraDimensionFieldMap"; - CREATE TRIGGER "update_JiraDimensionFieldMap_updatedAt" BEFORE UPDATE ON "JiraDimensionFieldMap" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - INSERT INTO "JiraDimensionFieldMap" ("teamId", "cloudId", "projectKey", "issueType", "dimensionName", "fieldId", "fieldName", "fieldType") - SELECT "Team"."id", jdf->>'cloudId', jdf->>'projectKey', '', jdf->>'dimensionName', jdf->>'fieldId', jdf->>'fieldName', jdf->>'fieldType' - FROM "Team", unnest("jiraDimensionFields") as jdf WHERE "jiraDimensionFields" != '{}' - ON CONFLICT ("teamId", "cloudId", "projectKey", "issueType", "dimensionName") DO NOTHING; - `) - // not dropping column yet to have an easy down migration - /* ALTER TABLE "Team" - DROP COLUMN IF EXISTS "jiraDimensionFields", - */ - - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - - // imagine an elaborate down migration here which aggregates the values back into a jsonb[] column and then imagine Postgres adding escape characters during array_agg rendering this useless - /* - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "jiraDimensionFields" JSONB[] NOT NULL DEFAULT '{}'; - - UPDATE "Team" - SET "jiraDimensionFields"=jdf.agg - FROM "Team" as t - INNER JOIN - (SELECT "teamId", array_agg(jsonb_build_object('cloudId', "cloudId", 'projectKey', "projectKey", 'dimensionName', "dimensionName", 'fieldId', "fieldId", 'fieldName', "fieldName", 'fieldType', "fieldType")) AS agg - FROM "JiraDimensionFieldMap" - GROUP BY "teamId") AS jdf - ON t.id = jdf."teamId"; - */ - await client.query(` - DROP TABLE IF EXISTS "JiraDimensionFieldMap"; - DROP TRIGGER IF EXISTS "update_JiraDimensionFieldMap_updatedAt" ON "JiraDimensionFieldMap"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1666387804873_userPatient0.ts b/packages/server/postgres/migrations/1666387804873_userPatient0.ts deleted file mode 100644 index 3c11d169c03..00000000000 --- a/packages/server/postgres/migrations/1666387804873_userPatient0.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - ADD COLUMN IF NOT EXISTS "isPatient0" BOOLEAN DEFAULT FALSE; - - DROP TABLE IF EXISTS "tmp_patient0"; - SELECT DISTINCT ON ("domain") "domain", "id" INTO TEMP "tmp_patient0" FROM "User" ORDER BY "domain", "createdAt"; - ALTER TABLE "tmp_patient0" ADD PRIMARY KEY ("id"); - - UPDATE "User" u - SET "isPatient0" = COALESCE((SELECT true FROM "tmp_patient0" p0 WHERE u."id" = p0."id"), false) ; - - DROP TABLE "tmp_patient0"; - - ALTER TABLE "User" - ALTER COLUMN "isPatient0" SET NOT NULL - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - DROP COLUMN IF EXISTS "isPatient0" - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1670328109485_addSummaryToDiscussion.ts b/packages/server/postgres/migrations/1670328109485_addSummaryToDiscussion.ts deleted file mode 100644 index 54dbefd255a..00000000000 --- a/packages/server/postgres/migrations/1670328109485_addSummaryToDiscussion.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Discussion" - ADD COLUMN IF NOT EXISTS "summary" VARCHAR(2000) -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Discussion" - DROP COLUMN IF EXISTS "summary"; -`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1670438374119_addAIUser.ts b/packages/server/postgres/migrations/1670438374119_addAIUser.ts deleted file mode 100644 index ee1a6d1e6a6..00000000000 --- a/packages/server/postgres/migrations/1670438374119_addAIUser.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - const picture = 'https://action-files.parabol.co/static/favicon.ico' - - const id = 'parabolAIUser' - const email = 'ai-user@parabol.co' - const preferredName = 'Parabol AI' - await client.query(` - INSERT INTO "User" ("id", "email", "preferredName", "picture") VALUES ('${id}', '${email}', '${preferredName}', '${picture}'); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DELETE FROM "User" WHERE "id" = 'parabolAIUser'; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1671536171066_updateTier.ts b/packages/server/postgres/migrations/1671536171066_updateTier.ts deleted file mode 100644 index 007d8d4bde6..00000000000 --- a/packages/server/postgres/migrations/1671536171066_updateTier.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TYPE "TierEnum" RENAME VALUE 'personal' TO 'starter'; - ALTER TYPE "TierEnum" RENAME VALUE 'pro' TO 'team'; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TYPE "TierEnum" RENAME VALUE 'starter' TO 'personal'; - ALTER TYPE "TierEnum" RENAME VALUE 'team' TO 'pro'; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1673613407246_updateAIUserPic.ts b/packages/server/postgres/migrations/1673613407246_updateAIUserPic.ts deleted file mode 100644 index 72967d9323f..00000000000 --- a/packages/server/postgres/migrations/1673613407246_updateAIUserPic.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - - const picture = 'https://action-files.parabol.co/static/favicon-with-more-padding.jpeg' - await client.query(` - UPDATE "User" SET "picture" = '${picture}' WHERE "id" = 'parabolAIUser'; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - const oldPicture = 'https://action-files.parabol.co/static/favicon.ico' - await client.query(` - UPDATE "User" SET "picture" = '${oldPicture}' WHERE "id" = 'parabolAIUser'; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1673629660481_addQualAIMeetingsCount.ts b/packages/server/postgres/migrations/1673629660481_addQualAIMeetingsCount.ts deleted file mode 100644 index ff6e7f55048..00000000000 --- a/packages/server/postgres/migrations/1673629660481_addQualAIMeetingsCount.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "qualAIMeetingsCount" INT NOT NULL DEFAULT 0; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - DROP COLUMN IF EXISTS "qualAIMeetingsCount"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1674074684762_deleteEmptyGroups.ts b/packages/server/postgres/migrations/1674074684762_deleteEmptyGroups.ts deleted file mode 100644 index 3c318b616d4..00000000000 --- a/packages/server/postgres/migrations/1674074684762_deleteEmptyGroups.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - await r.table('RetroReflectionGroup').filter({isActive: false}).delete().run() - await r.getPoolMaster()?.drain() -} - -export async function down() { - // can't undo a delete -} diff --git a/packages/server/postgres/migrations/1674237759799_meetingTemplates.ts b/packages/server/postgres/migrations/1674237759799_meetingTemplates.ts deleted file mode 100644 index 9e37396a7f0..00000000000 --- a/packages/server/postgres/migrations/1674237759799_meetingTemplates.ts +++ /dev/null @@ -1,47 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TYPE IF EXISTS "SharingScopeEnum"; - CREATE TYPE "SharingScopeEnum" AS ENUM ( - 'USER', - 'TEAM', - 'ORGANIZATION', - 'PUBLIC' - ); - CREATE TABLE IF NOT EXISTS "MeetingTemplate" ( - id VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - name VARCHAR(250) NOT NULL, - "teamId" VARCHAR(100) NOT NULL REFERENCES "Team"("id") ON DELETE CASCADE, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - scope "SharingScopeEnum" NOT NULL DEFAULT 'TEAM', - "orgId" VARCHAR(100) NOT NULL, - "parentTemplateId" VARCHAR(100), - "lastUsedAt" TIMESTAMP WITH TIME ZONE, - type "MeetingTypeEnum" NOT NULL, - "isStarter" BOOLEAN NOT NULL DEFAULT FALSE, - "isFree" BOOLEAN NOT NULL DEFAULT FALSE - ); - CREATE INDEX IF NOT EXISTS "idx_MeetingTemplate_teamId" ON "MeetingTemplate"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_MeetingTemplate_orgId" ON "MeetingTemplate"("orgId"); - DROP TRIGGER IF EXISTS "update_MeetingTemplate_updatedAt" ON "MeetingTemplate"; - CREATE TRIGGER "update_MeetingTemplate_updatedAt" BEFORE UPDATE ON "MeetingTemplate" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - // save for next migraiton: parentTemplateId -> REFERENCES "MeetingTemplate"("id") ON DELETE SET NULL - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "MeetingTemplate"; - DROP TYPE "SharingScopeEnum"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1676020597201_scheduledJobOrgIdIndex.ts b/packages/server/postgres/migrations/1676020597201_scheduledJobOrgIdIndex.ts deleted file mode 100644 index 86ad23d6dfc..00000000000 --- a/packages/server/postgres/migrations/1676020597201_scheduledJobOrgIdIndex.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export const up = async function () { - await connectRethinkDB() - try { - await r.table('ScheduledJob').indexCreate('orgId').run() - } catch {} - await r.getPoolMaster()?.drain() -} - -export const down = async function () { - await connectRethinkDB() - await r.table('ScheduledJob').indexDrop('orgId').run() - await r.getPoolMaster()?.drain() -} diff --git a/packages/server/postgres/migrations/1676299334703_addSeasonalTemplates.ts b/packages/server/postgres/migrations/1676299334703_addSeasonalTemplates.ts deleted file mode 100644 index ca9a5f74aa1..00000000000 --- a/packages/server/postgres/migrations/1676299334703_addSeasonalTemplates.ts +++ /dev/null @@ -1,203 +0,0 @@ -import {r} from 'rethinkdb-ts' -import {PALETTE} from '../../../client/styles/paletteV3' -import connectRethinkDB from '../../database/connectRethinkDB' - -const createdAt = new Date() - -const makeId = (name: string, type: 'template' | 'prompt') => { - const cleanedName = name - .replace(/[^0-9a-z-A-Z ]/g, '') // remove emojis and apostrophes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${type === 'template' ? 'Template' : 'Prompt'}` -} - -const makeTemplate = (name: string) => ({ - createdAt, - id: makeId(name, 'template'), - isActive: true, - name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: true, - isFree: false -}) - -const promptColors = [ - PALETTE.JADE_400, - PALETTE.TOMATO_500, - PALETTE.GOLD_300, - PALETTE.LILAC_500, - PALETTE.SKY_300, - PALETTE.TERRA_300, - PALETTE.FUSCIA_400, - PALETTE.SLATE_700 -] - -type PromptInfo = { - question: string - description: string - templateId: string - sortOrder: number -} - -const makePrompt = (promptInfo: PromptInfo, idx: number) => { - const {question, description, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColors[paletteIdx] - return { - createdAt, - description, - groupColor, - id: makeId(`${templateId}:${question}`, 'prompt'), - isActive: true, - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - title: question, - updatedAt: createdAt - } -} - -const templateNames = [ - 'Holi Retrospective', - 'Easter Retrospective', - 'Midsummer Retrospective', - 'Lunar New Year Retrospective' -] - -const promptsInfo = [ - { - question: 'Colors', - description: 'What color represents our recent work? Why?', - templateId: makeId(templateNames[0], 'template'), - sortOrder: 0 - }, - { - question: 'Music', - description: - 'Are we all dancing to the same rhythm? Where were we in sync? When did we fall out of sync?', - templateId: makeId(templateNames[0], 'template'), - sortOrder: 1 - }, - { - question: 'Dance', - description: 'What big wins make us want to dance? What moves or actions should we try next?', - templateId: makeId(templateNames[0], 'template'), - sortOrder: 2 - }, - { - question: 'Sweets', - description: 'Who deserves something sweet, kudos, or a word of thanks?', - templateId: makeId(templateNames[0], 'template'), - sortOrder: 3 - }, - { - question: 'Easter Eggs', - description: - 'What was hidden from sight or caught you by surprise? What did you learn or find out?', - templateId: makeId(templateNames[1], 'template'), - sortOrder: 0 - }, - { - question: 'Seeds', - description: - 'What new processes would we like to cultivate? Is there something that faded away that we should bring back?', - templateId: makeId(templateNames[1], 'template'), - sortOrder: 1 - }, - { - question: 'Hope', - description: 'What did you hope for? What are you hoping for next?', - templateId: makeId(templateNames[1], 'template'), - sortOrder: 2 - }, - { - question: 'Chocolate', - description: 'Who deserves some kudos or a word of thanks?', - templateId: makeId(templateNames[1], 'template'), - sortOrder: 3 - }, - { - question: 'Wreaths', - description: 'What processes and practices are binding us together and making us stronger?', - templateId: makeId(templateNames[2], 'template'), - sortOrder: 0 - }, - { - question: 'Schnapps', - description: 'What’s been hard to swallow, admit, or realize about our work?', - templateId: makeId(templateNames[2], 'template'), - sortOrder: 1 - }, - { - question: 'Longest Day', - description: 'What feels like it took too long or was never-ending?', - templateId: makeId(templateNames[2], 'template'), - sortOrder: 2 - }, - { - question: 'Strawberry Cake', - description: 'Who deserves some kudos or a word of thanks?', - templateId: makeId(templateNames[2], 'template'), - sortOrder: 3 - }, - { - question: 'Hongbao 🧧', - description: 'Who deserves a red envelope with kudos and some words of appreciation?', - templateId: makeId(templateNames[3], 'template'), - sortOrder: 0 - }, - { - question: 'Couplets 🎊 ', - description: 'What important messages should we remember for guidance?', - templateId: makeId(templateNames[3], 'template'), - sortOrder: 1 - }, - { - question: 'Firecracker 🧨', - description: 'What caught us by surprise or gave us a fright?', - templateId: makeId(templateNames[3], 'template'), - sortOrder: 2 - } -] - -const templates = templateNames.map((templateName) => makeTemplate(templateName)) -const reflectPrompts = promptsInfo.map((promptInfo, idx) => makePrompt(promptInfo, idx)) - -export const up = async function () { - try { - await connectRethinkDB() - await Promise.all([ - r.table('MeetingTemplate').insert(templates).run(), - r.table('ReflectPrompt').insert(reflectPrompts).run() - ]) - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export const down = async function () { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await connectRethinkDB() - await Promise.all([ - r.table('MeetingTemplate').getAll(r.args(templateIds)).delete().run(), - r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - ]) - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/postgres/migrations/1676341596550_updateOrgIdOnSAML.ts b/packages/server/postgres/migrations/1676341596550_updateOrgIdOnSAML.ts deleted file mode 100644 index 0c0d1ca4ff1..00000000000 --- a/packages/server/postgres/migrations/1676341596550_updateOrgIdOnSAML.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r - .table('SAML') - .update((row: any) => ({ - orgId: row('orgId').default(null) - })) - .run() - await r.table('SAML').indexCreate('orgId').run() - } catch {} - await r.getPoolMaster()?.drain() -} - -export async function down() { - await connectRethinkDB() - await r.table('SAML').indexDrop('orgId').run() - await r.getPoolMaster()?.drain() -} diff --git a/packages/server/postgres/migrations/1676461074304_NotificationOrgIdIndex.ts b/packages/server/postgres/migrations/1676461074304_NotificationOrgIdIndex.ts deleted file mode 100644 index 8ee9e2da75b..00000000000 --- a/packages/server/postgres/migrations/1676461074304_NotificationOrgIdIndex.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export const up = async function () { - await connectRethinkDB() - try { - await r.table('Notification').indexCreate('orgId').run() - } catch {} - - await r.getPoolMaster()?.drain() -} - -export const down = async function () { - await connectRethinkDB() - await r.table('Notification').indexDrop('orgId').run() - await r.getPoolMaster()?.drain() -} diff --git a/packages/server/postgres/migrations/1677272969994_meetingTemplatesMove.ts b/packages/server/postgres/migrations/1677272969994_meetingTemplatesMove.ts deleted file mode 100644 index c6d6b709fff..00000000000 --- a/packages/server/postgres/migrations/1677272969994_meetingTemplatesMove.ts +++ /dev/null @@ -1,97 +0,0 @@ -import {FirstParam} from 'parabol-client/types/generics' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' -import getPgp from '../getPgp' - -export async function up() { - await connectRethinkDB() - const {pgp, pg} = getPgp() - const batchSize = 1000 - // Create an index we can paginate on - try { - await r.table('MeetingTemplate').indexCreate('updatedAt').run() - await r.table('MeetingTemplate').indexWait().run() - } catch {} - - const columnSet = new pgp.helpers.ColumnSet( - [ - 'id', - 'createdAt', - 'isActive', - 'name', - 'teamId', - 'updatedAt', - 'scope', - 'orgId', - {name: 'parentTemplateId', def: null}, - {name: 'lastUsedAt', def: null}, - 'type', - {name: 'isStarter', def: false}, - {name: 'isFree', def: false} - ], - {table: 'MeetingTemplate'} - ) - - const getNextData = async (leftBoundCursor: Date | undefined) => { - const startAt = leftBoundCursor || r.minval - const nextBatch = await r - .table('MeetingTemplate') - // make sure leftBound is open so we don't get the same thing twice - // good for efficiency, but mostly because that could cause an infinite loop on the last batch - .between(startAt, r.maxval, {index: 'updatedAt', leftBound: 'open'}) - .orderBy({index: 'updatedAt'}) - .limit(batchSize) - .run() - // this is the last one, we know the updatedAt bucket isn't split (i.e. we know no other pending items share the same updatedAt) - if (nextBatch.length === 0) return null - // probably the 2nd to last batch. New updates may occur between now & the next time this gets called though! - if (nextBatch.length < batchSize) return nextBatch - // find the last complete bucket for updatedAt - const lastItem = nextBatch.pop() - const lastMatchingUpdatedAt = nextBatch.findLastIndex( - (item) => item.updatedAt !== lastItem.updatedAt - ) - if (lastMatchingUpdatedAt === -1) { - throw new Error( - 'batchSize is smaller than the number of items that share the same cursor. Increase batchSize' - ) - } - return nextBatch.slice(0, lastMatchingUpdatedAt + 1) - } - - await pg.tx('meetingTemplateTable', (task) => { - const fetchAndProcess: FirstParam = async ( - _index, - leftBoundCursor: undefined | Date - ) => { - const nextData = await getNextData(leftBoundCursor) - if (!nextData) return undefined - const insert = pgp.helpers.insert(nextData, columnSet) - const update = ` ON CONFLICT(id) DO UPDATE SET - "isActive" = EXCLUDED."isActive", - "name" = EXCLUDED."name", - "teamId" = EXCLUDED."teamId", - "updatedAt" = EXCLUDED."updatedAt", - "scope" = EXCLUDED."scope", - "orgId" = EXCLUDED."orgId", - "lastUsedAt" = EXCLUDED."lastUsedAt"` - const upsert = insert + update - await task.none(upsert) - return nextData.at(-1).updatedAt - } - return task.sequence(fetchAndProcess) - }) - await r.getPoolMaster()?.drain() -} - -export async function down() { - await connectRethinkDB() - await r.table('MeetingTemplate').indexDrop('updatedAt').run() - - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate"`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1677583911773_stripeQuantityMismatchLoggingNullableUserId.ts b/packages/server/postgres/migrations/1677583911773_stripeQuantityMismatchLoggingNullableUserId.ts deleted file mode 100644 index 0e5c5ff07c0..00000000000 --- a/packages/server/postgres/migrations/1677583911773_stripeQuantityMismatchLoggingNullableUserId.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "StripeQuantityMismatchLogging" - ADD COLUMN IF NOT EXISTS "orgId" VARCHAR(100), - ALTER COLUMN "userId" DROP NOT NULL, - ALTER COLUMN "userId" SET DEFAULT NULL; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - UPDATE "StripeQuantityMismatchLogging" SET "userId" = '' WHERE "userId" IS NULL; - ALTER TABLE "StripeQuantityMismatchLogging" - DROP COLUMN IF EXISTS "orgId", - ALTER COLUMN "userId" DROP DEFAULT, - ALTER COLUMN "userId" SET NOT NULL; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1680865284180_addDomainJoinRequestTable.ts b/packages/server/postgres/migrations/1680865284180_addDomainJoinRequestTable.ts deleted file mode 100644 index 997dc7946ab..00000000000 --- a/packages/server/postgres/migrations/1680865284180_addDomainJoinRequestTable.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "DomainJoinRequest" ( - "id" TEXT PRIMARY KEY, - "createdBy" VARCHAR(100) NOT NULL, - "domain" VARCHAR(100) CHECK (lower(domain) = domain) NOT NULL, - "expiresAt" TIMESTAMP WITH TIME ZONE DEFAULT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - FOREIGN KEY("createdBy") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - - CREATE UNIQUE INDEX IF NOT EXISTS "DomainJoinRequest_createdBy_domain_unique" - ON "DomainJoinRequest" ("createdBy", "domain"); - - DROP TRIGGER IF EXISTS "update_DomainJoinRequest_updatedAt" ON "DomainJoinRequest"; - CREATE TRIGGER "update_DomainJoinRequest_updatedAt" BEFORE UPDATE ON "DomainJoinRequest" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "DomainJoinRequest"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1682541572157_deleteUserRethink.ts b/packages/server/postgres/migrations/1682541572157_deleteUserRethink.ts deleted file mode 100644 index 08c99c62a93..00000000000 --- a/packages/server/postgres/migrations/1682541572157_deleteUserRethink.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - - try { - await r.tableDrop('User').run() - } catch (e) { - // table already dropped - } -} - -export async function down() { - // noop, if we recreated the table it wouldn't have the same indexes, etc. -} diff --git a/packages/server/postgres/migrations/1682541572158_templates4.ts b/packages/server/postgres/migrations/1682541572158_templates4.ts deleted file mode 100644 index 60e777f5856..00000000000 --- a/packages/server/postgres/migrations/1682541572158_templates4.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - - await client.query(` - CREATE TABLE IF NOT EXISTS "MeetingTemplateUserFavorite" ( - "userId" VARCHAR(100) NOT NULL REFERENCES "User"("id") ON DELETE CASCADE, - "templateId" VARCHAR(100) NOT NULL REFERENCES "MeetingTemplate"("id") ON DELETE CASCADE - ); - ALTER TABLE "MeetingTemplate" - DROP CONSTRAINT IF EXISTS "fk_parentTemplateId", - ADD CONSTRAINT "fk_parentTemplateId" - FOREIGN KEY("parentTemplateId") - REFERENCES "MeetingTemplate"("id") - ON DELETE SET NULL, - ADD COLUMN IF NOT EXISTS "illustrationUrl" VARCHAR(512), - ADD COLUMN IF NOT EXISTS "hideStartingAt" TIMESTAMP WITH TIME ZONE, - ADD COLUMN IF NOT EXISTS "hideEndingAt" TIMESTAMP WITH TIME ZONE, - ADD COLUMN IF NOT EXISTS "mainCategory" VARCHAR(100); - `) - // TODO: illustrationUrl NOT NULL, mainCategory NOT NULL, prime existing rows after server guarantees extra columns - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "MeetingTemplateUserFavorite"; - ALTER TABLE "MeetingTemplate" - DROP CONSTRAINT IF EXISTS "fk_parentTemplateId", - DROP COLUMN IF EXISTS "illustrationUrl", - DROP COLUMN IF EXISTS "hideStartingAt", - DROP COLUMN IF EXISTS "hideEndingAt", - DROP COLUMN IF EXISTS "mainCategory"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1682541573158_templates-primed.ts b/packages/server/postgres/migrations/1682541573158_templates-primed.ts deleted file mode 100644 index 7a5c04b79d0..00000000000 --- a/packages/server/postgres/migrations/1682541573158_templates-primed.ts +++ /dev/null @@ -1,161 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const templatesIllustrations = { - aChristmasCarolRetrospectiveTemplate: 'aChristmasCarolRetrospectiveTemplate.png', - alwaysBeLearningRetrospectiveTemplate: 'alwaysBeLearningRetrospectiveTemplate.png', - diwaliRetrospectiveTemplate: 'diwaliRetrospectiveTemplate.png', - dreamTeamRetrospectiveTemplate: 'dreamTeamRetrospectiveTemplate.png', - dropAddKeepImproveDAKITemplate: 'dakiTemplate.png', - easterRetrospectiveTemplate: 'easterRetrospectiveTemplate.png', - energyLevelsTemplate: 'energyLevelsTemplate.png', - fourLsTemplate: 'fourLsTemplate.png', - gladSadMadTemplate: 'gladSadMadTemplate.png', - halloweenRetrospectiveTemplate: 'halloweenRetrospectiveTemplate.png', - handsOnDeckActivityTemplate: 'handsOnDeckActivityTemplate.png', - heardSeenRespectedHSRTemplate: 'heardSeenRespectedHSRTemplate.png', - herosJourneyTemplate: 'herosJourneyTemplate.png', - highlightsLowlightsTemplate: 'highlightsLowlightsTemplate.png', - holiRetrospectiveTemplate: 'holiRetrospectiveTemplate.png', - hopesAndFearsTemplate: 'hopesAndFearsTemplate.png', - hotAirBalloonTemplate: 'hotAirBalloonTemplate.png', - keepProblemTryTemplate: 'keepProblemTryTemplate.png', - leanCoffeeTemplate: 'leanCoffeeTemplate.png', - lunarNewYearRetrospectiveTemplate: 'lunarNewYearRetrospectiveTemplate.png', - marieKondoRetrospectiveTemplate: 'marieKondoRetrospectiveTemplate.png', - midsummerRetrospectiveTemplate: 'midsummerRetrospectiveTemplate.png', - mountainClimberTemplate: 'mountainClimberTemplate.png', - newYearRetrospectiveTemplate: 'newYearRetrospectiveTemplate.png', - original4Template: 'original4Template.png', - questionsCommentsConcernsTemplate: 'questionsCommentsConcernsTemplate.png', - roseThornBudTemplate: 'roseThornBudTemplate.png', - sWOTAnalysisTemplate: 'sWOTAnalysisTemplate.png', - saMoLoTemplate: 'saMoLoTemplate.png', - sailboatTemplate: 'sailboatTemplate.png', - scrumValuesRetrospectiveTemplate: 'scrumValuesRetrospectiveTemplate.png', - sixThinkingHatsTemplate: 'sixThinkingHatsTemplate.png', - speedCarTemplate: 'speedCarTemplate.png', - starfishTemplate: 'starfishTemplate.png', - startStopContinueTemplate: 'startStopContinueTemplate.png', - superheroRetrospectiveTemplate: 'superheroRetrospectiveTemplate.png', - surprisedWorriedInspiredTemplate: 'surprisedWorriedInspiredTemplate.png', - teamCharterTemplate: 'teamCharterTemplate.png', - teamRetreatPlanningTemplate: 'teamRetreatPlanningTemplate.png', - thanksgivingRetrospectiveTemplate: 'thanksgivingRetrospectiveTemplate.png', - threeLittlePigsTemplate: 'threeLittlePigsTemplate.png', - wRAPTemplate: 'wRAPTemplate.png', - whatWentWellTemplate: 'whatWentWellTemplate.png', - winningStreakTemplate: 'winningStreakTemplate.png', - workingStuckTemplate: 'workingStuckTemplate.png', - // poker - estimatedEffortTemplate: 'estimatedEffortTemplate.png', - wsjfTemplate: 'wsjfTemplate.png' - } - - const seasonalTemplates = { - thanksgivingRetrospectiveTemplate: ['2020-11-30', '2020-10-14'], - halloweenRetrospectiveTemplate: ['2020-11-07', '2020-09-21'], - aChristmasCarolRetrospectiveTemplate: ['2020-01-01', '2019-11-15'], - newYearRetrospectiveTemplate: ['2020-01-08', '2019-11-22'], - holiRetrospectiveTemplate: ['2020-04-01', '2020-02-13'], - easterRetrospectiveTemplate: ['2020-04-16', '2020-02-28'], - midsummerRetrospectiveTemplate: ['2020-07-01', '2020-05-15'], - lunarNewYearRetrospectiveTemplate: ['2020-02-25', '2019-12-15'] - } - - const categories = { - sWOTAnalysisTemplate: 'strategy', - teamCharterTemplate: 'strategy', - teamRetreatPlanningTemplate: 'strategy', - questionsCommentsConcernsTemplate: 'feedback' - } - - const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `store/Organization/aGhostOrg/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } - const hostPath = process.env.CDN_BASE_URL!.replace(/^\/+/, '') - return `https://${hostPath}/${partialPath}` - } - - const client = new Client(getPgConfig()) - await client.connect() - - // set defaults for illustrationUrl and mainCategory - await Promise.all([ - client.query( - ` - UPDATE "MeetingTemplate" - SET "illustrationUrl" = $1, "mainCategory" = 'retrospective' - WHERE "type" = 'retrospective'; - `, - [getTemplateIllustrationUrl('gladSadMadTemplate.png')] - ), - client.query( - ` - UPDATE "MeetingTemplate" - SET "illustrationUrl" = $1, "mainCategory" = 'estimation' - WHERE "type" = 'poker'; - `, - [getTemplateIllustrationUrl('estimatedEffortTemplate.png')] - ) - ]) - - // set illustrationUrl specifics - await Promise.all( - Object.entries(templatesIllustrations).map(async ([templateId, filename]) => { - const href = getTemplateIllustrationUrl(filename) - return client.query( - ` - UPDATE "MeetingTemplate" - SET "illustrationUrl" = $2 - WHERE id = $1 OR "parentTemplateId" = $1; - `, - [templateId, href] - ) - }) - ) - - // set category specifics - await Promise.all( - Object.entries(categories).map(async ([templateId, category]) => { - return client.query( - ` - UPDATE "MeetingTemplate" - SET "mainCategory" = $2 - WHERE id = $1 OR "parentTemplateId" = $1; - `, - [templateId, category] - ) - }) - ) - - // set seasonal dates - await Promise.all( - Object.entries(seasonalTemplates).map(async ([templateId, dates]) => { - const [hideStartingAt, hideEndingAt] = dates - return client.query( - ` - UPDATE "MeetingTemplate" - SET "hideStartingAt" = $1, "hideEndingAt" = $2 - WHERE id = $3; - `, - [hideStartingAt, hideEndingAt, templateId] - ) - }) - ) - - await client.query(` - ALTER TABLE "MeetingTemplate" - ALTER COLUMN "illustrationUrl" SET NOT NULL, - ALTER COLUMN "mainCategory" SET NOT NULL; - `) - await client.end() -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1683902222006_domainJoinRequestAutoIncrementId.ts b/packages/server/postgres/migrations/1683902222006_domainJoinRequestAutoIncrementId.ts deleted file mode 100644 index 2c79f69b44c..00000000000 --- a/packages/server/postgres/migrations/1683902222006_domainJoinRequestAutoIncrementId.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "DomainJoinRequest"; - - CREATE TABLE IF NOT EXISTS "DomainJoinRequest" ( - "id" SERIAL PRIMARY KEY, - "createdBy" VARCHAR(100) NOT NULL, - "domain" VARCHAR(100) CHECK (lower(domain) = domain) NOT NULL, - "expiresAt" TIMESTAMP WITH TIME ZONE DEFAULT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - FOREIGN KEY("createdBy") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - - CREATE UNIQUE INDEX IF NOT EXISTS "DomainJoinRequest_createdBy_domain_unique" - ON "DomainJoinRequest" ("createdBy", "domain"); - - DROP TRIGGER IF EXISTS "update_DomainJoinRequest_updatedAt" ON "DomainJoinRequest"; - CREATE TRIGGER "update_DomainJoinRequest_updatedAt" BEFORE UPDATE ON "DomainJoinRequest" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "DomainJoinRequest"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1684250022646_teamHealthPhase.ts b/packages/server/postgres/migrations/1684250022646_teamHealthPhase.ts deleted file mode 100644 index b1f0c0bdaa5..00000000000 --- a/packages/server/postgres/migrations/1684250022646_teamHealthPhase.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {r, RValue} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - // Noop, using the feature will however create data which is not backwards compatible, thus only a down migration -} - -export async function down() { - await connectRethinkDB() - // There are cleaner ways, but this is just for dev and it works - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - .filter(r.row('phases').contains((row) => row('phaseType').eq('TEAM_HEALTH'))) - .update((row: RValue) => ({ - phases: row('phases').difference(row('phases').filter({phaseType: 'TEAM_HEALTH'})) - })) - .run() - await r - .table('MeetingSettings') - .filter({meetingType: 'retrospective'}) - .filter(r.row('phaseTypes').contains('TEAM_HEALTH')) - .update({phaseTypes: r.row('phaseTypes').difference(['TEAM_HEALTH'])}) - .run() - await r.getPoolMaster()?.drain() -} diff --git a/packages/server/postgres/migrations/1685721573097_addPrePostMortemTemplates.ts b/packages/server/postgres/migrations/1685721573097_addPrePostMortemTemplates.ts deleted file mode 100644 index 86d6f9ce92e..00000000000 --- a/packages/server/postgres/migrations/1685721573097_addPrePostMortemTemplates.ts +++ /dev/null @@ -1,1111 +0,0 @@ -import {PALETTE} from 'parabol-client/styles/paletteV3' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' -import getPgp from '../getPgp' - -interface Prompt { - question: string - description?: string -} - -interface Template { - name: string - type: 'premortem' | 'postmortem' - prompts: Prompt[] -} - -const NEW_TEMPLATE_CONFIGS: Template[] = [ - { - name: 'Budget review post-mortem', - type: 'postmortem', - prompts: [ - { - question: '💰 How did our actual spending compare to the initial budget?', - description: "Compare your project's financial performance against the planned budget." - }, - { - question: '📊 What were the major cost drivers?', - description: "Identify factors that most impacted your project's financial performance." - }, - { - question: '💼 Where can we make adjustments for better budget allocation?', - description: - 'Determine opportunities to optimize spending and allocate resources more effectively.' - } - ] - }, - { - name: 'Control range post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🎛️ What was within our control?', - description: 'Identify factors your team could influence or manage.' - }, - { - question: '🌪️ What was beyond our control?', - description: - "Recognize external forces affecting the project but outside your team's influence." - }, - { - question: '📈 What can we improve in our control range?', - description: 'Determine areas within your control to adjust for future projects.' - } - ] - }, - { - name: 'Process improvement post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🔄 What processes worked well during the project?', - description: "Find the successful aspects of your project's workflows and methodologies." - }, - { - question: '⚠️ What processes could be improved?', - description: - "Pinpoint areas where your project's procedures faced challenges or fell short." - }, - { - question: '🔬 What innovations or creative solutions emerged during the project?', - description: 'Identify any inventive methods or ideas that proved beneficial.' - }, - { - question: '📝 How can we optimize our workflows for future projects?', - description: 'Develop strategies to enhance processes and adopt or update best practices.' - } - ] - }, - { - name: 'Simple post-mortem', - type: 'postmortem', - prompts: [ - { - question: '✅ What went well during the project?', - description: 'Highlight the successful aspects of the project.' - }, - { - question: '❌ What could be improved for future projects?', - description: 'Identify the project’s challenges and issues.' - }, - { - question: '📝 What actions can we take to address these improvements?', - description: 'Outline actions to boost future projects.' - } - ] - }, - { - name: 'Agile post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🔄 How well did we adapt and iterate throughout the project?', - description: - "Evaluate your team's ability to respond to changes and implement iterations during the project." - }, - { - question: '🤝 How effective were our collaboration and communication?', - description: "Assess your team's quality of teamwork, information sharing, and cooperation." - }, - { - question: '🎯 What Agile principles can we improve upon for future projects?', - description: - 'Find areas where your team can strengthen their application of Agile methodologies.' - } - ] - }, - { - name: 'Time management post-mortem', - type: 'postmortem', - prompts: [ - { - question: '⏱️ How accurate were our initial time estimates?', - description: - "Gauge the precision of your team's time forecasts and compare them to the actual time invested in project tasks." - }, - { - question: '📅 Which tasks took longer than expected, and why?', - description: - 'Identify tasks that required more time than anticipated and discuss the reasons behind this.' - }, - { - question: '🚧 What obstacles impacted our time management?', - description: - 'Uncover the factors that caused delays or inefficiencies in the project and learn from them.' - }, - { - question: - '⚙️ What strategies can we implement to improve time management in future projects?', - description: - "Develop action plans to master time allocation and scheduling, boosting your team's productivity and punctuality." - } - ] - }, - { - name: 'IT project post-mortem', - type: 'postmortem', - prompts: [ - { - question: - '💻 Which technology tools and platforms were most beneficial during the project?', - description: 'Identify the most valuable and effective components of your technology stack.' - }, - { - question: '🔧 What gaps or challenges did we face in our IT infrastructure?', - description: 'Recognize any technology-related issues or shortcomings.' - }, - { - question: '📈 How can we enhance our technology stack for future projects?', - description: - 'Formulate strategies to upgrade your IT infrastructure and tools, considering the insights from this post-mortem.' - } - ] - }, - { - name: 'Software project post-mortem', - type: 'postmortem', - prompts: [ - { - question: '👩‍💻 How did our development process perform during the project?', - description: 'Assess the effectiveness and efficiency of your software development process.' - }, - { - question: '🔎 How successful were our testing and quality assurance efforts?', - description: 'Evaluate the thoroughness and accuracy of your testing and QA processes.' - }, - { - question: '🚀 How smoothly did our deployment and maintenance procedures go?', - description: - 'Review the efficiency and success of your software deployment and maintenance.' - } - ] - }, - { - name: 'Engineering post-mortem', - type: 'postmortem', - prompts: [ - { - question: '📐 Did our project design and planning meet expectations?', - description: - "Assess how your project's design and planning helped meet your engineering goals." - }, - { - question: '🔨 How well did we execute the project and overcome technical challenges?', - description: - "Assess your team's ability to manage the project and tackle technical obstacles." - }, - { - question: '🤓 What nuggets of wisdom can we mine for future engineering projects?', - description: - 'Identify best practices, areas for improvement, and other insights to optimize future engineering projects.' - } - ] - }, - { - name: 'Post-mortem analysis', - type: 'postmortem', - prompts: [ - { - question: "🎯 What were our project's objectives, and did we achieve them?", - description: 'Re-examine your project goals and evaluate your performance against them.' - }, - { - question: '📉 What challenges or obstacles did we face?', - description: 'Identify the challenges that shaped your project.' - }, - { - question: "👍️ What worked well and what didn't?", - description: 'Highlight successes and areas that need improvement.' - }, - { - question: '🗒️ What can we learn and apply to future projects?', - description: 'Create actionable plans from the insights the other questions revealed.' - } - ] - }, - { - name: 'Post-incident review', - type: 'postmortem', - prompts: [ - { - question: '🚩 What incidents or issues disrupted our flow?', - description: 'List the incidents that took place.' - }, - { - question: '🌳 What were the root causes and contributing factors?', - description: - 'Identify the underlying causes and other elements that played a role in the problems you faced.' - }, - { - question: '🔍 What can we learn from these incidents?', - description: 'Reflect on the lessons these incidents provided.' - }, - { - question: - '🛠️ What preventive measures can we put in place for similar incidents in the future?', - description: 'Develop strategies to minimize recurrence and enhance future responses.' - } - ] - }, - { - name: 'Incident response post-mortem', - type: 'postmortem', - prompts: [ - { - question: '⚠️ What was our incident response strategy, and how well did it work?', - description: "Review your team's actions and decisions in handling incidents." - }, - { - question: - '⛑️ Which aspects of our response were most effective, and which were less successful?', - description: 'Identify areas where your team excelled and those needing improvement.' - }, - { - question: '🚨 Were our incident response plans and procedures effective?', - description: 'Evaluate the usefulness of existing approaches and protocols.' - }, - { - question: '📈 What improvements can we make to our incident response for future projects?', - description: "Develop strategies to improve your team's incident readiness." - } - ] - }, - { - name: 'Incident impact post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🔍 What was the impact of the incident?', - description: - 'List the incidents that took place during the project and discuss their effects.' - }, - { - question: '🌳 What was the root cause?', - description: 'Identify the underlying causes of each incident.' - }, - { - question: '💡 What lessons have we learned from this incident?', - description: 'Determine the key takeaways from each incident.' - }, - { - question: '🔧 What changes can we make to prevent similar incidents in the future?', - description: 'Create plans to minimize the chances of recurrence.' - } - ] - }, - { - name: 'Risk management post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🎲 What risks did we identify, and how did we manage them?', - description: "Review the identified risks and your team's risk mitigation strategies." - }, - { - question: '📊 How effective were our risk management efforts?', - description: "Assess the success of your team's risk mitigation strategies." - }, - { - question: '🚧 What unexpected risks or challenges emerged?', - description: 'Explore unforeseen risks and their impact on the project.' - }, - { - question: '🔮 How can we improve risk management for future projects?', - description: - "Define actions and procedures to enhance your team's ability to navigate uncertainties." - } - ] - }, - { - name: 'Team performance post-mortem', - type: 'postmortem', - prompts: [ - { - question: '👥 How did our team dynamics impact the project?', - description: "Assess the effect of your team's interpersonal relationships on the project." - }, - { - question: '🗣️ What communication challenges did we face?', - description: 'Identify any communication issues that arose and their impact on the project.' - }, - { - question: '🤝 How can we improve collaboration for future projects?', - description: 'Determine areas for growth and develop strategies to enhance teamwork.' - } - ] - }, - { - name: 'Feature launch post-mortem', - type: 'postmortem', - prompts: [ - { - question: '📣 What feedback did we receive from customers?', - description: 'Collect and categorize customer feedback from various channels.' - }, - { - question: '🎯 What were the most common customer pain points?', - description: 'Identify recurring issues and areas of dissatisfaction.' - }, - { - question: '🏆️ What aspects did customers appreciate the most?', - description: - "Highlight the strengths and successful elements of the project from the customers' perspective." - }, - { - question: '🔄 What changes can we make based on customer feedback?', - description: - 'Think of ways to address customer concerns and enhance your products or services.' - } - ] - }, - { - name: 'Stakeholder satisfaction post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🤝 How aligned were our project outcomes with stakeholder expectations?', - description: - "Assess the alignment between your team's deliverables and stakeholder expectations." - }, - { - question: '📣 How effective was our communication with stakeholders?', - description: - 'Evaluate the clarity, frequency, and impact of your communications with stakeholders.' - }, - { - question: '🚩 What challenges did we encounter in managing stakeholder expectations?', - description: - 'Identify any misunderstandings or disconnects that arose between the team and stakeholders.' - }, - { - question: '🎯 What steps can we take to improve stakeholder engagement in future projects?', - description: - 'Develop approaches to strengthen stakeholder relationships, improve communication, and align project outcomes with stakeholder expectations.' - } - ] - }, - { - name: 'Blameless post-mortem', - type: 'postmortem', - prompts: [ - { - question: '📉 What challenges arose during the project?', - description: - 'Describe the difficulties encountered, focusing on the situation and the impact, not on individuals or their actions.' - }, - { - question: '🌱 What can we learn from these situations?', - description: - 'Reflect on the issues from a blameless perspective, emphasizing the lessons learned rather than assigning fault.' - }, - { - question: '🔧 What changes can we make to prevent these issues in the future?', - description: - 'Suggest improvements or preventive measures, keeping in mind the goal is to improve the process, not to blame people.' - } - ] - }, - { - name: 'Remote work post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🌍 What worked well in our remote work environment?', - description: 'Highlight the positive aspects of your remote work dynamics.' - }, - { - question: '📞 Where did our digital communication fall flat?', - description: 'Identify areas where remote communication could be improved.' - }, - { - question: '💻 What specific remote work challenges did we face?', - description: 'Pinpoint the unique obstacles that emerged due to the distributed work setup.' - }, - { - question: '🌐 What steps can we take to make remote work more seamless?', - description: 'Brainstorm ways to enhance remote collaboration and streamline communication.' - } - ] - }, - { - name: 'Superhero post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🦸 What unique superpowers does each team member possess?', - description: 'Discover the unique talents of each individual.' - }, - { - question: '💥 How did these superpowers drive the project forward?', - description: "Analyze how individual strengths influenced the project's outcome." - }, - { - question: '💪 What opportunities lie ahead for each superhero?', - description: "Discuss ways to further leverage each team member's talents." - }, - { - question: '🎯 How can we better align our superpowers with project objectives?', - description: 'Consider how to match individual strengths with specific project goals.' - } - ] - }, - { - name: 'Time travel post-mortem', - type: 'postmortem', - prompts: [ - { - question: '⌛ If we could go back in time, what would we change?', - description: 'Discuss changes your team would make if given a second chance.' - }, - { - question: '🚀 What did we learn for future projects?', - description: - 'Imagine how the lessons and insights gained from this project will improve future endeavors.' - }, - { - question: "🔍 How did this project shape our team's growth and development?", - description: "Imagine how this project impacts your team's evolution." - }, - { - question: '🌈 How will changes we make now improve future projects?', - description: 'Consider how actions you take now will play out in future projects.' - } - ] - }, - { - name: 'Movie director post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🎬 What was the plot of our project movie?', - description: "Narrate the project's journey, including pivotal events and plot twists." - }, - { - question: '🎥 How did each cast member contribute to the plot?', - description: "Discuss each team member's roles and actions." - }, - { - question: '🏔️ What were the climaxes and plot holes in our project movie?', - description: 'Identify key victories and hurdles.' - }, - { - question: '2️⃣ What ingredients do we need for a blockbuster sequel?', - description: 'Reflect on elements that could make future projects even more successful.' - } - ] - }, - { - name: 'Game show post-mortem', - type: 'postmortem', - prompts: [ - { - question: '🎮 What were the key "rounds" of our project game show?', - description: 'Break down the project into distinct stages.' - }, - { - question: '🏆 What were the wins and losses during each round?', - description: 'Identify successes and challenges at each stage.' - }, - { - question: "🎉 How did each contestant contribute to the game show's finale?", - description: "Discuss each individual's roles and actions." - }, - { - question: '🕹️ What game rules should we modify for the next season?', - description: 'Consider changes that could improve the process for future projects.' - } - ] - }, - { - name: 'Why did the project fail pre-mortem', - type: 'premortem', - prompts: [ - { - question: '⁉️ Why did the project fail?', - description: - 'What could go wrong and prevent us meeting our goals? Try to focus on things that could reasonably put the project off track. ' - } - ] - }, - { - name: 'Success and failure pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🏆 What does success look like?', - description: 'Envision the end goal and the milestones that mark the path to success.' - }, - { - question: '🚧 What does failure look like?', - description: - 'Consider the potential obstacles and challenges that could derail the project.' - } - ] - }, - { - name: 'Team efficiency pre-mortem', - type: 'premortem', - prompts: [ - { - question: '⏳ What slowed us down?', - description: "Identify processes or factors that could hinder your team's progress." - }, - { - question: '🚧 Where could we get stuck?', - description: 'Anticipate potential bottlenecks or obstacles that may stall the project.' - }, - { - question: '🆘 Where might we need extra help?', - description: - 'Recognize areas where your team may require additional resources or expertise.' - }, - { - question: '🎯 What caused us to miss the deadline?', - description: - 'Envision scenarios that could lead to missed deadlines and develop strategies to avoid them.' - } - ] - }, - { - name: 'Obstacle course pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🚧 Hurdles', - description: - 'What barriers might we encounter that require us to change course or adapt our approach?' - }, - { - question: '🕳️ Pitfalls', - description: - 'What hidden traps or pitfalls could cause setbacks, delays, or negative impacts on the project?' - }, - { - question: '🌪️ Twists', - description: - 'What unexpected changes or surprises might require quick thinking and flexibility?' - }, - { - question: '🎽 Teamwork', - description: - 'How can we best support each other and collaborate to overcome these challenges and reach our goals?' - } - ] - }, - { - name: 'Timeline pre-mortem', - type: 'premortem', - prompts: [ - { - question: '📆 Start', - description: - 'What challenges might we face at the beginning of the project? Consider potential obstacles such as team formation, initial planning, and resource allocation.' - }, - { - question: '🕰️ Middle', - description: - 'What challenges might we face during the middle of the project? Reflect on possible hurdles like shifting deadlines, team fatigue, and evolving priorities.' - }, - { - question: '🏁 End', - description: - 'What challenges might we face at the end of the project? Envision potential difficulties like last-minute changes, finalizing deliverables, and closing the project effectively.' - } - ] - }, - { - name: 'Resource allocation pre-mortem', - type: 'premortem', - prompts: [ - { - question: '💼 People', - description: 'Are we lacking any essential skills or expertise for the project?' - }, - { - question: '⏳ Time', - description: - 'Are there any time constraints or scheduling conflicts that could hinder the project?' - }, - { - question: '💰 Budget', - description: - 'Are there any budget limitations or financial risks that could impact the project?' - }, - { - question: '🛠️ Tools', - description: - 'Are there any gaps in our toolset or technology stack that could impact the project?' - } - ] - }, - { - name: 'Best/worst case scenario pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🤦 Worst case scenario', - description: - 'What does the worst case scenario look like? Consider the most significant setbacks and obstacles your project could face.' - }, - { - question: '🙌 Best case scenario', - description: - "What does the best case scenario look like? Imagine your project's ultimate success and the milestones that lead to it." - }, - { - question: '⛳ Actions', - description: - 'What actions can we take to transform the worst-case scenario into the best-case scenario? Develop strategic plans and contingencies to turn challenges into opportunities.' - } - ] - }, - { - name: 'Risks and precautions pre-mortem', - type: 'premortem', - prompts: [ - { - question: '💥 Risks', - description: 'What are the biggest risks we could face during the project?' - }, - { - question: '⛑️ Precautions', - description: 'What precautions should we take now to mitigate these risks?' - } - ] - }, - { - name: 'Blind spot pre-mortem', - type: 'premortem', - prompts: [ - { - question: '👁️ Visible', - description: 'What obvious threats should we mitigate?' - }, - { - question: '👻 Invisible', - description: 'What hidden or unknown threats should we pre-empt?' - } - ] - }, - { - name: 'What if... pre-mortem', - type: 'premortem', - prompts: [ - { - question: 'What if [insert risk]', - description: 'Customize this question to address a specific risk.' - }, - { - question: 'What if [insert challenge]', - description: 'Adapt this question to tackle another unique challenge.' - }, - { - question: 'What if [insert concern]', - description: 'Tailor this question to explore an additional concern.' - } - ] - }, - { - name: 'Threat level pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🔴 Severe', - description: - 'What severe issues could we run into that derail the project? (Requires a separate meeting or review.)' - }, - { - question: '🟡 Elevated', - description: - 'What moderate issues would we run into that delay the project? (Warrants 10-20 minutes of discussion during the pre-mortem.)' - }, - { - question: '🟢 Low', - description: - 'What low-risk issues should we expect? (Max. 5 minutes of discussion during the pre-mortem)' - } - ] - }, - { - name: 'How likely to fail pre-mortem', - type: 'premortem', - prompts: [ - { - question: '💯 Highly likely', - description: 'What issues are we highly likely to face?' - }, - { - question: '🤔 Somewhat likely', - description: 'What issues are we likely to face?' - }, - { - question: '🤷 Possible', - description: 'What issues could we possibly face?' - } - ] - }, - { - name: 'Excited and worried pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🤩 What are you excited about?' - }, - { - question: '😨 What are you worried about?' - } - ] - }, - { - name: 'Iguana, Crocodile, Komodo Dragon pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🦎 Iguana', - description: 'What minor issues can we quickly and easily resolve now?' - }, - { - question: '🐊 Crocodile', - description: 'What significant and foreseeable threats does this project face?' - }, - { - question: '🐉 Komodo Dragon', - description: 'What big, scary, and unpredictable challenges might we encounter?' - } - ] - }, - { - name: 'Glass half-empty pre-mortem', - type: 'premortem', - prompts: [ - { - question: '⏳ Glass half full', - description: 'What do we expect to go well?' - }, - { - question: '⌛ Glass half empty', - description: 'What do we worry will go wrong?' - } - ] - }, - { - name: 'Safari pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🦒 Giraffe', - description: 'What risks can we see from a long way off and pre-empt now?' - }, - { - question: '🐘 Elephant', - description: 'What concerns you that nobody else is discussing?' - }, - { - question: '🐅 Cheetah', - description: 'What issues are hidden in plain sight, ready to pounce on us?' - }, - { - question: '🐒 Monkey', - description: 'What early warning signs could indicate something is going wrong?' - } - ] - }, - { - name: 'Mad scientist pre-mortem', - type: 'premortem', - prompts: [ - { - question: '⚗️ Crazy experiments', - description: 'What wild and unexpected risks might we face?' - }, - { - question: '🧪 Freak accidents', - description: 'What surprising challenges could throw our project off course?' - }, - { - question: '💡 Innovative solutions', - description: 'How can we invent creative strategies to counter these threats?' - } - ] - }, - { - name: 'Uncertain waters pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🌊 Hidden reefs', - description: 'What unforeseen obstacles or issues could cause us to run aground?' - }, - { - question: '🌀 Storms', - description: 'What significant challenges or crises might we face during the project?' - }, - { - question: '⚓ Anchors', - description: 'What might hold us back, slow our progress, or hinder our efficiency?' - }, - { - question: '🏝️ Safe harbors', - description: 'How can we best prepare to weather these challenges and uncertainties?' - } - ] - }, - { - name: 'Fortune teller pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🔮 Crystal ball', - description: 'What potential issues do we foresee arising during the project?' - }, - { - question: '🌟 Stars align', - description: "How might these issues impact our project's success or failure?" - }, - { - question: '✨ Changing fate', - description: - 'What actions can we take now to alter the course of our project for the better?' - } - ] - }, - { - name: 'Stakeholder concerns pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🤵 Executive concerns', - description: 'What concerns might our executives have about the project?' - }, - { - question: '👩‍💼 Team concerns', - description: 'What concerns might our team members have about the project?' - }, - { - question: '🤝 Client concerns', - description: 'What concerns might our clients have about the project?' - }, - { - question: '🌐 Community concerns', - description: 'What concerns might the broader community have about the project?' - } - ] - }, - { - name: 'Communication risks pre-mortem', - type: 'premortem', - prompts: [ - { - question: '📣 Internal communication', - description: 'What communication issues might arise within the team?' - }, - { - question: '💬 External communication', - description: 'What communication issues might arise with stakeholders or clients?' - }, - { - question: '📩 Information flow', - description: - 'What issues might hinder the flow of information between team members or stakeholders?' - }, - { - question: '🤯 Misunderstandings', - description: 'What potential misunderstandings or misconceptions could cause problems?' - } - ] - }, - { - name: 'Scrum sprint pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🎯 Product backlog', - description: 'What challenges could arise in maintaining a healthy and prioritized backlog?' - }, - { - question: '📊 Sprint planning', - description: 'What obstacles might we face in effectively planning and executing sprints?' - }, - { - question: '🔄 Retrospectives', - description: - 'What challenges could impact the effectiveness of our retrospectives and continuous improvement efforts?' - }, - { - question: '🚀 Sprint review', - description: - 'What issues could affect our ability to showcase our progress to stakeholders?' - } - ] - }, - { - name: 'Scrum roles pre-mortem', - type: 'premortem', - prompts: [ - { - question: '🏃 Scrum Master', - description: 'What challenges might the Scrum Master face in facilitating the project?' - }, - { - question: '👨‍💻 Developers', - description: 'What challenges might the developers face in executing the project?' - }, - { - question: '📚 Product Owner', - description: - 'What challenges might the Product Owner face in managing the product backlog and aligning with stakeholders?' - } - ] - } -] - -const createdAt = new Date() - -const makeId = (name: string, type: 'template' | 'prompt') => { - // FIXME truncate to 100 characters - const cleanedName = name - .replace(/[^0-9a-zA-Z ]/g, '') // remove emojis, apostrophes, and dashes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${type === 'template' ? 'Template' : 'Prompt'}` -} - -const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `Organization/aGhostOrg/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } else { - const {CDN_BASE_URL} = process.env - if (!CDN_BASE_URL) throw new Error('Missng Env: CDN_BASE_URL') - const hostPath = CDN_BASE_URL.replace(/^\/+/, '') - return `https://${hostPath}/store/${partialPath}` - } -} - -const makeTemplate = (template: Template) => ({ - createdAt, - id: makeId(template.name, 'template'), - isActive: true, - name: template.name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: false, - isFree: true, - illustrationUrl: getTemplateIllustrationUrl( - template.type === 'postmortem' ? 'postMortemTemplate.png' : 'preMortemTemplate.png' - ), - mainCategory: template.type, - lastUsedAt: null, - parentTemplateId: null -}) - -const promptColors = [ - PALETTE.JADE_400, - PALETTE.TOMATO_500, - PALETTE.GOLD_300, - PALETTE.LILAC_500, - PALETTE.SKY_300, - PALETTE.TERRA_300, - PALETTE.FUSCIA_400, - PALETTE.SLATE_700 -] - -type PromptInfo = { - question: string - description?: string - templateId: string - sortOrder: number -} - -const makePrompt = (promptInfo: PromptInfo, idx: number) => { - const {question, description, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColors[paletteIdx] - return { - createdAt, - description: description ?? '', - groupColor, - id: makeId(`${templateId}:${question}`, 'prompt'), - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - updatedAt: createdAt, - removedAt: null - } -} - -const templates = NEW_TEMPLATE_CONFIGS.map((templateConfig) => makeTemplate(templateConfig)) -let colorIndex = 0 -const reflectPrompts = NEW_TEMPLATE_CONFIGS.map((templateConfig) => { - return templateConfig.prompts.map((prompt, idx) => { - colorIndex++ - return makePrompt( - { - question: prompt.question, - description: prompt.description, - sortOrder: idx, - templateId: makeId(templateConfig.name, 'template') - }, - colorIndex - ) - }) -}).flat() - -export async function up() { - const {pgp, pg} = getPgp() - const columnSet = new pgp.helpers.ColumnSet( - [ - 'id', - 'createdAt', - 'isActive', - 'name', - 'teamId', - 'updatedAt', - 'scope', - 'orgId', - 'type', - 'illustrationUrl', - 'mainCategory', - {name: 'isStarter', def: false}, - {name: 'isFree', def: false} - ], - {table: 'MeetingTemplate'} - ) - const insert = pgp.helpers.insert(templates, columnSet) - await pg.none(insert) - try { - await connectRethinkDB() - await r.table('ReflectPrompt').insert(reflectPrompts).run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export async function down() { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await connectRethinkDB() - await r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = ANY($1);`, [templateIds]) - await client.end() -} diff --git a/packages/server/postgres/migrations/1686226640890_addTeamHealthToAllMeetingSettingsRetrospective.ts b/packages/server/postgres/migrations/1686226640890_addTeamHealthToAllMeetingSettingsRetrospective.ts deleted file mode 100644 index acfbef081d0..00000000000 --- a/packages/server/postgres/migrations/1686226640890_addTeamHealthToAllMeetingSettingsRetrospective.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {r, RValue} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - await r - .table('MeetingSettings') - .filter({meetingType: 'retrospective'}) - .update((row: RValue) => ({ - phaseTypes: r.branch( - row('phaseTypes').contains('TEAM_HEALTH'), - row('phaseTypes'), - row('phaseTypes').contains('checkin'), - row('phaseTypes').insertAt(1, 'TEAM_HEALTH'), - row('phaseTypes').prepend('TEAM_HEALTH') - ) - })) - .run() - await r.getPoolMaster()?.drain() -} - -export async function down() { - await connectRethinkDB() - await r - .table('MeetingSettings') - .filter({meetingType: 'retrospective'}) - .update((row: RValue) => ({ - phaseTypes: row('phaseTypes').difference(['TEAM_HEALTH']) - })) - .run() - await r.getPoolMaster()?.drain() -} diff --git a/packages/server/postgres/migrations/1686226641890_fixed-activities.ts b/packages/server/postgres/migrations/1686226641890_fixed-activities.ts deleted file mode 100644 index 6cff4e72290..00000000000 --- a/packages/server/postgres/migrations/1686226641890_fixed-activities.ts +++ /dev/null @@ -1,186 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `Organization/aGhostOrg/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } else { - const {CDN_BASE_URL} = process.env - if (!CDN_BASE_URL) throw new Error('Missng Env: CDN_BASE_URL') - const hostPath = CDN_BASE_URL.replace(/^\/+/, '') - return `https://${hostPath}/store/${partialPath}` - } - } - - const client = new Client(getPgConfig()) - await client.connect() - - // I made a mistake in the URL for local CDNs including the /store pathname. - // The pre/post mortem templates do not have this problem. - const fixIllustrationURLforLocalCDNs = async () => { - await client.query( - `UPDATE "MeetingTemplate" SET "illustrationUrl" = $1 WHERE "type" = 'retrospective';`, - [getTemplateIllustrationUrl('gladSadMadTemplate.png')] - ) - await client.query( - `UPDATE "MeetingTemplate" SET "illustrationUrl" = $1 WHERE "type" = 'poker';`, - [getTemplateIllustrationUrl('estimatedEffortTemplate.png')] - ) - const templatesIllustrations = { - aChristmasCarolRetrospectiveTemplate: 'aChristmasCarolRetrospectiveTemplate.png', - alwaysBeLearningRetrospectiveTemplate: 'alwaysBeLearningRetrospectiveTemplate.png', - diwaliRetrospectiveTemplate: 'diwaliRetrospectiveTemplate.png', - dreamTeamRetrospectiveTemplate: 'dreamTeamRetrospectiveTemplate.png', - dropAddKeepImproveDAKITemplate: 'dakiTemplate.png', - easterRetrospectiveTemplate: 'easterRetrospectiveTemplate.png', - energyLevelsTemplate: 'energyLevelsTemplate.png', - fourLsTemplate: 'fourLsTemplate.png', - gladSadMadTemplate: 'gladSadMadTemplate.png', - halloweenRetrospectiveTemplate: 'halloweenRetrospectiveTemplate.png', - handsOnDeckActivityTemplate: 'handsOnDeckActivityTemplate.png', - heardSeenRespectedHSRTemplate: 'heardSeenRespectedHSRTemplate.png', - herosJourneyTemplate: 'herosJourneyTemplate.png', - highlightsLowlightsTemplate: 'highlightsLowlightsTemplate.png', - holiRetrospectiveTemplate: 'holiRetrospectiveTemplate.png', - hopesAndFearsTemplate: 'hopesAndFearsTemplate.png', - hotAirBalloonTemplate: 'hotAirBalloonTemplate.png', - keepProblemTryTemplate: 'keepProblemTryTemplate.png', - leanCoffeeTemplate: 'leanCoffeeTemplate.png', - lunarNewYearRetrospectiveTemplate: 'lunarNewYearRetrospectiveTemplate.png', - marieKondoRetrospectiveTemplate: 'marieKondoRetrospectiveTemplate.png', - midsummerRetrospectiveTemplate: 'midsummerRetrospectiveTemplate.png', - mountainClimberTemplate: 'mountainClimberTemplate.png', - newYearRetrospectiveTemplate: 'newYearRetrospectiveTemplate.png', - original4Template: 'original4Template.png', - questionsCommentsConcernsTemplate: 'questionsCommentsConcernsTemplate.png', - roseThornBudTemplate: 'roseThornBudTemplate.png', - sWOTAnalysisTemplate: 'sWOTAnalysisTemplate.png', - saMoLoTemplate: 'saMoLoTemplate.png', - sailboatTemplate: 'sailboatTemplate.png', - scrumValuesRetrospectiveTemplate: 'scrumValuesRetrospectiveTemplate.png', - sixThinkingHatsTemplate: 'sixThinkingHatsTemplate.png', - speedCarTemplate: 'speedCarTemplate.png', - starfishTemplate: 'starfishTemplate.png', - startStopContinueTemplate: 'startStopContinueTemplate.png', - superheroRetrospectiveTemplate: 'superheroRetrospectiveTemplate.png', - surprisedWorriedInspiredTemplate: 'surprisedWorriedInspiredTemplate.png', - teamCharterTemplate: 'teamCharterTemplate.png', - teamRetreatPlanningTemplate: 'teamRetreatPlanningTemplate.png', - thanksgivingRetrospectiveTemplate: 'thanksgivingRetrospectiveTemplate.png', - threeLittlePigsTemplate: 'threeLittlePigsTemplate.png', - wRAPTemplate: 'wRAPTemplate.png', - whatWentWellTemplate: 'whatWentWellTemplate.png', - winningStreakTemplate: 'winningStreakTemplate.png', - workingStuckTemplate: 'workingStuckTemplate.png', - // poker - estimatedEffortTemplate: 'estimatedEffortTemplate.png', - wsjfTemplate: 'wsjfTemplate.png' - } - // set illustrationUrl specifics - await Promise.all( - Object.entries(templatesIllustrations).map(async ([templateId, filename]) => { - const href = getTemplateIllustrationUrl(filename) - return client.query( - ` - UPDATE "MeetingTemplate" - SET "illustrationUrl" = $2 - WHERE id = $1 OR "parentTemplateId" = $1; - `, - [templateId, href] - ) - }) - ) - } - - await fixIllustrationURLforLocalCDNs() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = 'action' OR id = 'teamPrompt';`) - const teamPromptActivity = { - id: 'teamPrompt', - type: 'teamPrompt', - name: 'Standup', - team: {name: 'Parabol'}, - category: 'standup', - isRecommended: true, - isFree: true, - createdAt: new Date('2023-04-01'), - illustrationUrl: getTemplateIllustrationUrl('teamPrompt.png'), - isActive: true, - isStarter: true, - lastUsedAt: null, - mainCategory: 'standup', - orgId: 'aGhostOrg', - parentTemplateId: null, - scope: 'PUBLIC', - teamId: 'aGhostTeam', - updatedAt: new Date('2023-04-01') - } - - const checkinActivity = { - id: 'action', - type: 'action', - name: 'Check-in', - team: {name: 'Parabol'}, - category: 'standup', - isRecommended: true, - isFree: true, - createdAt: new Date('2016-06-01'), - illustrationUrl: getTemplateIllustrationUrl('action.png'), - isActive: true, - isStarter: true, - lastUsedAt: null, - mainCategory: 'standup', - orgId: 'aGhostOrg', - parentTemplateId: null, - scope: 'PUBLIC', - teamId: 'aGhostTeam', - updatedAt: new Date('2016-06-01') - } - const fixedActivities = [teamPromptActivity, checkinActivity] - await Promise.all( - fixedActivities.map((activity) => { - const { - id, - name, - teamId, - orgId, - parentTemplateId, - type, - scope, - lastUsedAt, - isStarter, - isFree, - mainCategory, - illustrationUrl - } = activity - - return client.query( - `INSERT INTO "MeetingTemplate" (id, name, "teamId", "orgId", "parentTemplateId", type, scope, "lastUsedAt", "isStarter", "isFree", "mainCategory", "illustrationUrl") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, - [ - id, - name, - teamId, - orgId, - parentTemplateId, - type, - scope, - lastUsedAt, - isStarter, - isFree, - mainCategory, - illustrationUrl - ] - ) - }) - ) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = 'action' OR id = 'teamPrompt';`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1687822236394_activity-illustrations.ts b/packages/server/postgres/migrations/1687822236394_activity-illustrations.ts deleted file mode 100644 index b88d9e92f60..00000000000 --- a/packages/server/postgres/migrations/1687822236394_activity-illustrations.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - // I messed up & forgot to add the "/template" part of the URL in the last migration - await client.query(` - UPDATE "MeetingTemplate" - SET "illustrationUrl" = REPLACE("illustrationUrl", '/aGhostOrg/', '/aGhostOrg/template/') - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1688980408626_useIndexForTeamHealthAnswers.ts b/packages/server/postgres/migrations/1688980408626_useIndexForTeamHealthAnswers.ts deleted file mode 100644 index 890f6d4e147..00000000000 --- a/packages/server/postgres/migrations/1688980408626_useIndexForTeamHealthAnswers.ts +++ /dev/null @@ -1,88 +0,0 @@ -import {r, RValue} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - // date of the addTeamHealthToAllMeetingSettingsRetrospective migration - .filter((row: RValue) => row('createdAt').ge(new Date(1686226640890))) - .update((row: RValue) => ({ - phases: row('phases').map((phase: RValue) => - r.branch( - phase('phaseType').ne('TEAM_HEALTH'), - phase, - phase.merge({ - stages: phase('stages').map((stage: RValue) => - stage.merge({ - votes: stage('votes').map((vote: RValue) => - r.branch( - vote('label').eq('😀'), - { - vote: 0, - userId: vote('userId') - }, - vote('label').eq('😐'), - { - vote: 1, - userId: vote('userId') - }, - { - vote: 2, - userId: vote('userId') - } - ) - ) - }) - ) - }) - ) - ) - })) - .run() - await r.getPoolMaster()?.drain() -} - -export async function down() { - await connectRethinkDB() - await r - .table('NewMeeting') - .filter({meetingType: 'retrospective'}) - // date of the addTeamHealthToAllMeetingSettingsRetrospective migration - .filter((row: RValue) => row('createdAt').ge(new Date(1686226640890))) - .update((row: RValue) => ({ - phases: row('phases').map((phase: RValue) => - r.branch( - phase('phaseType').ne('TEAM_HEALTH'), - phase, - phase.merge({ - stages: phase('stages').map((stage: RValue) => - stage.merge({ - votes: stage('votes').map((vote: RValue) => - r.branch( - vote('vote').eq(0), - { - label: '😀', - userId: vote('userId') - }, - vote('vote').eq(1), - { - label: '😐', - userId: vote('userId') - }, - { - label: '😢', - userId: vote('userId') - } - ) - ) - }) - ) - }) - ) - ) - })) - .run() - await r.getPoolMaster()?.drain() -} diff --git a/packages/server/postgres/migrations/1689031398651_del-team-meetingTemplate.ts b/packages/server/postgres/migrations/1689031398651_del-team-meetingTemplate.ts deleted file mode 100644 index d49b2681476..00000000000 --- a/packages/server/postgres/migrations/1689031398651_del-team-meetingTemplate.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {r} from 'rethinkdb-ts' - -const connectRethinkDB = async () => { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) -} - -export async function up() { - await connectRethinkDB() - try { - // 20220329101759-dropTeams never ran in prod, deleting the Team table here - await Promise.allSettled([ - r.tableDrop('Team').run(), - r.tableDrop('MeetingTemplate').run(), - r.tableDrop('GQLRequest').run(), - r.tableDrop('DuplicateEmails').run(), - r.tableDrop('SecureDomain').run() - ]) - } catch { - // noop - } - await r.getPoolMaster()?.drain() -} - -export async function down() { - // can't undo a drop -} diff --git a/packages/server/postgres/migrations/1689183718138_RetroReflectionGroup-part1-write.ts b/packages/server/postgres/migrations/1689183718138_RetroReflectionGroup-part1-write.ts deleted file mode 100644 index 5708e2262a8..00000000000 --- a/packages/server/postgres/migrations/1689183718138_RetroReflectionGroup-part1-write.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "RetroReflectionGroup" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - "meetingId" VARCHAR(100) NOT NULL, - "promptId" VARCHAR(100) NOT NULL, - "sortOrder" INT NOT NULL DEFAULT 0, - "voterIds" VARCHAR(100)[] NOT NULL DEFAULT '{}', - "smartTitle" VARCHAR(255), - "title" VARCHAR(255), - "summary" VARCHAR(2000) - ); - CREATE INDEX IF NOT EXISTS "idx_RetroReflectionGroup_meetingId" ON "RetroReflectionGroup"("meetingId"); - CREATE INDEX IF NOT EXISTS "idx_RetroReflectionGroup_promptId" ON "RetroReflectionGroup"("promptId"); - DROP TRIGGER IF EXISTS "update_RetroReflectionGroup_updatedAt" ON "RetroReflectionGroup"; - CREATE TRIGGER "update_RetroReflectionGroup_updatedAt" BEFORE UPDATE ON "RetroReflectionGroup" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "RetroReflectionGroup"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1689705702984_addDiscussionPromptQuestionsToRetroReflectionGroup.ts b/packages/server/postgres/migrations/1689705702984_addDiscussionPromptQuestionsToRetroReflectionGroup.ts deleted file mode 100644 index a2be0ef667b..00000000000 --- a/packages/server/postgres/migrations/1689705702984_addDiscussionPromptQuestionsToRetroReflectionGroup.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "RetroReflectionGroup" - ADD COLUMN IF NOT EXISTS "discussionPromptQuestion" VARCHAR(2000) -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "RetroReflectionGroup" - DROP COLUMN IF EXISTS "discussionPromptQuestion"; -`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1689949187848_addTeamInsights.ts b/packages/server/postgres/migrations/1689949187848_addTeamInsights.ts deleted file mode 100644 index 29f2a898ef4..00000000000 --- a/packages/server/postgres/migrations/1689949187848_addTeamInsights.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "insightsUpdatedAt" TIMESTAMP WITH TIME ZONE, - -- 3 most used emojis in format [{id: string, count: number}] - ADD COLUMN IF NOT EXISTS "mostUsedEmojis" JSONB, - -- 3 most used retro templates in format [{templateId: string, count: number}] - ADD COLUMN IF NOT EXISTS "topRetroTemplates" JSONB, - -- meeting engagement in format {meetingType: string, engagement: number} - ADD COLUMN IF NOT EXISTS "meetingEngagement" JSONB; - END - $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - DROP COLUMN "mostUsedEmojis", - DROP COLUMN "insightsUpdatedAt", - DROP COLUMN "topRetroTemplates", - DROP COLUMN "meetingEngagement"; - END - $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1690364653869_addOneOnOneMeetingType.ts b/packages/server/postgres/migrations/1690364653869_addOneOnOneMeetingType.ts deleted file mode 100644 index c9b7b397a55..00000000000 --- a/packages/server/postgres/migrations/1690364653869_addOneOnOneMeetingType.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - - const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `Organization/aGhostOrg/template/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } else { - const {CDN_BASE_URL} = process.env - if (!CDN_BASE_URL) throw new Error('Missng Env: CDN_BASE_URL') - const hostPath = CDN_BASE_URL.replace(/^\/+/, '') - return `https://${hostPath}/store/${partialPath}` - } - } - - const oneOnOneActivity = { - id: 'oneOnOneAction', - type: 'action', - name: 'One on One', - isFree: true, - illustrationUrl: getTemplateIllustrationUrl('action.png'), - isStarter: true, - lastUsedAt: null, - mainCategory: 'standup', - orgId: 'aGhostOrg', - parentTemplateId: null, - scope: 'PUBLIC', - teamId: 'aGhostTeam' - } - const { - id, - name, - teamId, - orgId, - parentTemplateId, - type, - scope, - lastUsedAt, - isStarter, - isFree, - mainCategory, - illustrationUrl - } = oneOnOneActivity - - await client.query( - `INSERT INTO "MeetingTemplate" (id, name, "teamId", "orgId", "parentTemplateId", type, scope, "lastUsedAt", "isStarter", "isFree", "mainCategory", "illustrationUrl") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, - [ - id, - name, - teamId, - orgId, - parentTemplateId, - type, - scope, - lastUsedAt, - isStarter, - isFree, - mainCategory, - illustrationUrl - ] - ) - - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = 'oneOnOneAction';`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1690544776592_addGcalIntegrationProvider.ts b/packages/server/postgres/migrations/1690544776592_addGcalIntegrationProvider.ts deleted file mode 100644 index 1e2f1fa991d..00000000000 --- a/packages/server/postgres/migrations/1690544776592_addGcalIntegrationProvider.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TYPE "IntegrationProviderServiceEnum" ADD VALUE IF NOT EXISTS 'gcal'; - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - DELETE FROM "IntegrationProvider" WHERE "service" = 'gcal'; - ALTER TYPE "IntegrationProviderServiceEnum" RENAME TO "IntegrationProviderServiceEnum_delete"; - CREATE TYPE "IntegrationProviderServiceEnum" AS ENUM ( - 'gitlab', - 'mattermost', - 'jiraServer', - 'azureDevOps', - 'msTeams' - ); - ALTER TABLE "IntegrationProvider" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum"; - ALTER TABLE "TeamMemberIntegrationAuth" - ALTER COLUMN "service" TYPE "IntegrationProviderServiceEnum" USING "service"::text::"IntegrationProviderServiceEnum", - DROP TYPE "IntegrationProviderServiceEnum_delete"; - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1691421540088_updateRetroReflectionGroupSortOrderType.ts b/packages/server/postgres/migrations/1691421540088_updateRetroReflectionGroupSortOrderType.ts deleted file mode 100644 index 679a089b3ab..00000000000 --- a/packages/server/postgres/migrations/1691421540088_updateRetroReflectionGroupSortOrderType.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "RetroReflectionGroup" - ALTER COLUMN "sortOrder" TYPE DOUBLE PRECISION; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "RetroReflectionGroup" - ALTER COLUMN "sortOrder" TYPE INT; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1691422128820_fixOrganizationTier.ts b/packages/server/postgres/migrations/1691422128820_fixOrganizationTier.ts deleted file mode 100644 index b7725ffcaa8..00000000000 --- a/packages/server/postgres/migrations/1691422128820_fixOrganizationTier.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r - .table('Organization') - .filter(r.row('tier').eq('personal')) - .update({tier: 'starter'}) - .run() - } catch {} - await r.getPoolMaster()?.drain() -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1692638249976_isOneOnOneTeam.ts b/packages/server/postgres/migrations/1692638249976_isOneOnOneTeam.ts deleted file mode 100644 index 40940b7f4e9..00000000000 --- a/packages/server/postgres/migrations/1692638249976_isOneOnOneTeam.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "isOneOnOneTeam" BOOLEAN NOT NULL DEFAULT FALSE; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - DROP COLUMN IF EXISTS "isOneOnOneTeam"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1692650094687_TeamMeetingTemplate.ts b/packages/server/postgres/migrations/1692650094687_TeamMeetingTemplate.ts deleted file mode 100644 index 4f65c550690..00000000000 --- a/packages/server/postgres/migrations/1692650094687_TeamMeetingTemplate.ts +++ /dev/null @@ -1,96 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -interface TeamMeetingTemplate { - teamId: string - templateId: string - lastUsedAt: Date -} - -const connectRethinkDB = async () => { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - CREATE TABLE IF NOT EXISTS "TeamMeetingTemplate" ( - "teamId" VARCHAR(100) NOT NULL, - "templateId" VARCHAR(100) NOT NULL, - "lastUsedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - UNIQUE ("teamId","templateId"), - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_templateId" - FOREIGN KEY("templateId") - REFERENCES "MeetingTemplate"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TeamMeetingTemplate_teamId" ON "TeamMeetingTemplate"("teamId"); - `.execute(pg) - - // If we miss a new team or 2 that gets created while this is running that's OK! - // They don't have any used templates to start with - const teamIdsRes = await pg.selectFrom('Team').select('id').execute() - const teamIds = teamIdsRes.map((row) => row.id) - const BATCH_SIZE = 10000 - - for (let i = 0; i < 10000; i++) { - const start = i * BATCH_SIZE - const end = start + BATCH_SIZE - const teamIdBatch = teamIds.slice(start, end) - if (teamIdBatch.length === 0) break - const rowsToInsert = (await r - .table('NewMeeting') - .getAll(r.args(teamIdBatch), {index: 'teamId'}) - .group((row) => ({teamId: row('teamId'), templateId: row('templateId')})) - .max('createdAt')('createdAt') - .ungroup() - .map((row) => ({ - teamId: row('group')('teamId').default(null), - templateId: row('group')('templateId').default(null), - lastUsedAt: row('reduction') - })) - .filter((row: any) => row('templateId').default(null).ne(null)) - .run()) as TeamMeetingTemplate[] - - // it's possible a templateId exists in NewMeeting, but not in MeetingTemplate - const attemptedTemplateIds = rowsToInsert.map((r) => r.templateId) - if (attemptedTemplateIds.length === 0) continue - const validTemplates = await pg - .selectFrom('MeetingTemplate') - .select('id') - .where('id', 'in', attemptedTemplateIds) - .execute() - if (validTemplates.length === 0) continue - const validTemplateIds = new Set(validTemplates.map(({id}) => id)) - const validRowsToInsert = rowsToInsert.filter((row) => validTemplateIds.has(row.templateId)) - await pg - .insertInto('TeamMeetingTemplate') - .values(validRowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DROP TABLE IF EXISTS "TeamMeetingTemplate";`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1693991480688_truncateReflectPromptIds.ts b/packages/server/postgres/migrations/1693991480688_truncateReflectPromptIds.ts deleted file mode 100644 index a17dd2f0de1..00000000000 --- a/packages/server/postgres/migrations/1693991480688_truncateReflectPromptIds.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {r, RDatum} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -/** - * The prompt id is used as a foreign key in the ReflectionGroup table and thus should not be excessively long => truncate it to 100 characters. - */ -export async function up() { - await connectRethinkDB() - await r - .table('ReflectPrompt') - .insert( - r - .table('ReflectPrompt') - .filter((row: RDatum) => row('id').count().gt(100)) - .map((row: RDatum) => row.merge({id: row('id').slice(0, 100)})) - ) - .run() - await r - .table('ReflectPrompt') - .filter((row: RDatum) => row('id').count().gt(100)) - .delete() - .run() - await r.getPoolMaster()?.drain() -} - -export async function down() { - // no down migration, as long as ids are unique, we're fine -} diff --git a/packages/server/postgres/migrations/1694191002164_migrateSAML.ts b/packages/server/postgres/migrations/1694191002164_migrateSAML.ts deleted file mode 100644 index 1bf2899fc13..00000000000 --- a/packages/server/postgres/migrations/1694191002164_migrateSAML.ts +++ /dev/null @@ -1,95 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {RDatum, r} from 'rethinkdb-ts' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -const connectRethinkDB = async () => { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - // I had to normalize domains to its own table to guarantee uniqueness (and make indexing easier) - await sql` - CREATE TABLE IF NOT EXISTS "SAML" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "lastUpdatedBy" VARCHAR(100) NOT NULL DEFAULT 'aGhostUser', - "url" VARCHAR(2056), - "metadata" VARCHAR(65536), - "orgId" VARCHAR(100) UNIQUE, - CONSTRAINT "fk_lastUpdatedBy" - FOREIGN KEY("lastUpdatedBy") - REFERENCES "User"("id") - ON DELETE SET DEFAULT - ); - CREATE INDEX IF NOT EXISTS "idx_SAML_orgId" ON "SAML"("orgId"); - DROP TRIGGER IF EXISTS "update_SAML_updatedAt" ON "SAML"; - CREATE TRIGGER "update_SAML_updatedAt" BEFORE UPDATE ON "SAML" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - CREATE TABLE IF NOT EXISTS "SAMLDomain" ( - "domain" VARCHAR(255) CHECK (lower(domain) = domain) PRIMARY KEY, - "samlId" VARCHAR(100), - CONSTRAINT "fk_samlId" - FOREIGN KEY("samlId") - REFERENCES "SAML"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_SAMLDomain_samlId" ON "SAMLDomain"("samlId"); - `.execute(pg) - - // Attempt to assign an orgId to existing SAML records - // It isn't perfect because some orgs have downgraded, leaving orphaned SAML records - // This is why orgId is nullable for now - await r - .table('SAML') - .update( - (saml: RDatum) => ({ - orgId: r - .table('Organization') - .getAll(r.args(saml('domains')), {index: 'activeDomain'}) - .limit(1) - .nth(0)('id') - .default(null) - }), - {nonAtomic: true} - ) - .run() - - const existingSAMLs = await r.table('SAML').coerceTo('array').run() - if (existingSAMLs.length === 0) return - const nextSAMLs = existingSAMLs.map((saml) => { - const {domains, ...rest} = saml - return rest - }) - - const nextSAMLDomains = [] as {domain: string; samlId: string}[] - existingSAMLs.forEach((saml) => { - saml.domains.forEach((domain: any) => { - nextSAMLDomains.push({domain, samlId: saml.id}) - }) - }) - - await pg.insertInto('SAML').values(nextSAMLs).execute() - await pg.insertInto('SAMLDomain').values(nextSAMLDomains).execute() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DROP TABLE IF EXISTS "SAMLDomain"; DROP TABLE IF EXISTS "SAML"; `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1695293482618_addFreemailDomain.ts b/packages/server/postgres/migrations/1695293482618_addFreemailDomain.ts deleted file mode 100644 index cb46398628f..00000000000 --- a/packages/server/postgres/migrations/1695293482618_addFreemailDomain.ts +++ /dev/null @@ -1,4802 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -const HUBSPOT_FREEMAIL_DOMAINS = [ - '0-mail.com', - '027168.com', - '0815.su', - '0sg.net', - '10mail.org', - '10minutemail.co.za', - '11mail.com', - '123.com', - '123box.net', - '123india.com', - '123mail.cl', - '123mail.org', - '123qwe.co.uk', - '126.com', - '139.com', - '150mail.com', - '150ml.com', - '15meg4free.com', - '163.com', - '16mail.com', - '188.com', - '189.cn', - '1ce.us', - '1chuan.com', - '1coolplace.com', - '1freeemail.com', - '1funplace.com', - '1internetdrive.com', - '1mail.ml', - '1mail.net', - '1me.net', - '1mum.com', - '1musicrow.com', - '1netdrive.com', - '1nsyncfan.com', - '1pad.de', - '1under.com', - '1webave.com', - '1webhighway.com', - '1zhuan.com', - '2-mail.com', - '20email.eu', - '20mail.in', - '20mail.it', - '212.com', - '21cn.com', - '24horas.com', - '2911.net', - '2980.com', - '2bmail.co.uk', - '2d2i.com', - '2die4.com', - '2trom.com', - '3000.it', - '30minutesmail.com', - '3126.com', - '321media.com', - '33mail.com', - '37.com', - '3ammagazine.com', - '3dmail.com', - '3email.com', - '3g.ua', - '3mail.ga', - '3xl.net', - '444.net', - '4email.com', - '4email.net', - '4mg.com', - '4newyork.com', - '4warding.net', - '4warding.org', - '4x4man.com', - '50mail.com', - '60minutemail.com', - '6ip.us', - '6mail.cf', - '6paq.com', - '74gmail.com', - '74.ru', - '7mail.ga', - '7mail.ml', - '88.am', - '8848.net', - '8mail.ga', - '8mail.ml', - '97rock.com', - '99experts.com', - 'a45.in', - 'aaamail.zzn.com', - 'aamail.net', - 'aapt.net.au', - 'aaronkwok.net', - 'abbeyroadlondon.co.uk', - 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com', - 'abcflash.net', - 'abdulnour.com', - 'aberystwyth.com', - 'about.com', - 'abusemail.de', - 'abv.bg', - 'abwesend.de', - 'abyssmail.com', - 'ac20mail.in', - 'academycougars.com', - 'acceso.or.cr', - 'access4less.net', - 'accessgcc.com', - 'accountant.com', - 'acdcfan.com', - 'ace-of-base.com', - 'acmemail.net', - 'acninc.net', - 'activist.com', - 'adam.com.au', - 'add3000.pp.ua', - 'addcom.de', - 'address.com', - 'adelphia.net', - 'adexec.com', - 'adfarrow.com', - 'adios.net', - 'adoption.com', - 'ados.fr', - 'adrenalinefreak.com', - 'advalvas.be', - 'advantimo.com', - 'aeiou.pt', - 'aemail4u.com', - 'aeneasmail.com', - 'afreeinternet.com', - 'africamail.com', - 'africamel.net', - 'ag.us.to', - 'agoodmail.com', - 'ahaa.dk', - 'ahk.jp', - 'aichi.com', - 'aim.com', - 'aircraftmail.com', - 'airforce.net', - 'airforceemail.com', - 'airpost.net', - 'ajacied.com', - 'ajaxapp.net', - 'ak47.hu', - 'aknet.kg', - 'albawaba.com', - 'alex4all.com', - 'alexandria.cc', - 'algeria.com', - 'alhilal.net', - 'alibaba.com', - 'alice.it', - 'alive.cz', - 'aliyun.com', - 'allergist.com', - 'allmail.net', - 'alloymail.com', - 'allracing.com', - 'allsaintsfan.com', - 'alpenjodel.de', - 'alphafrau.de', - 'alskens.dk', - 'altavista.com', - 'altavista.net', - 'altavista.se', - 'alternativagratis.com', - 'alumni.com', - 'alumnidirector.com', - 'alvilag.hu', - 'amail.com', - 'amazonses.com', - 'amele.com', - 'america.hm', - 'ameritech.net', - 'amnetsal.com', - 'amorki.pl', - 'amrer.net', - 'amuro.net', - 'amuromail.com', - 'ananzi.co.za', - 'andylau.net', - 'anfmail.com', - 'angelfire.com', - 'angelic.com', - 'animail.net', - 'animalhouse.com', - 'animalwoman.net', - 'anjungcafe.com', - 'annsmail.com', - 'ano-mail.net', - 'anonmails.de', - 'anonymous.to', - 'anote.com', - 'another.com', - 'anotherdomaincyka.tk', - 'anotherwin95.com', - 'anti-social.com', - 'antisocial.com', - 'antispam24.de', - 'antongijsen.com', - 'antwerpen.com', - 'anymoment.com', - 'anytimenow.com', - 'aol.com', - 'aon.at', - 'apexmail.com', - 'apmail.com', - 'apollo.lv', - 'aport.ru', - 'aport2000.ru', - 'appraiser.net', - 'approvers.net', - 'arabia.com', - 'arabtop.net', - 'archaeologist.com', - 'arcor.de', - 'arcotronics.bg', - 'arcticmail.com', - 'argentina.com', - 'aristotle.org', - 'army.net', - 'armyspy.com', - 'arnet.com.ar', - 'art-en-ligne.pro', - 'artlover.com', - 'artlover.com.au', - 'as-if.com', - 'asdasd.nl', - 'asean-mail.com', - 'asheville.com', - 'asia-links.com', - 'asia-mail.com', - 'asiafind.com', - 'asianavenue.com', - 'asiancityweb.com', - 'asiansonly.net', - 'asianwired.net', - 'asiapoint.net', - 'ass.pp.ua', - 'assala.com', - 'assamesemail.com', - 'astroboymail.com', - 'astrolover.com', - 'astrosfan.com', - 'astrosfan.net', - 'asurfer.com', - 'atheist.com', - 'athenachu.net', - 'atina.cl', - 'atl.lv', - 'atlaswebmail.com', - 'atmc.net', - 'atozasia.com', - 'atrus.ru', - 'att.net', - 'attglobal.net', - 'attymail.com', - 'au.ru', - 'auctioneer.net', - 'ausi.com', - 'aussiemail.com.au', - 'austin.rr.com', - 'australia.edu', - 'australiamail.com', - 'austrosearch.net', - 'autoescuelanerja.com', - 'autograf.pl', - 'autorambler.ru', - 'avh.hu', - 'avia-tonic.fr', - 'awsom.net', - 'axoskate.com', - 'ayna.com', - 'azazazatashkent.tk', - 'azimiweb.com', - 'azmeil.tk', - 'bachelorboy.com', - 'bachelorgal.com', - 'backpackers.com', - 'backstreet-boys.com', - 'backstreetboysclub.com', - 'bagherpour.com', - 'baldmama.de', - 'baldpapa.de', - 'ballyfinance.com', - 'bangkok.com', - 'bangkok2000.com', - 'bannertown.net', - 'baptistmail.com', - 'baptized.com', - 'barcelona.com', - 'bareed.ws', - 'bartender.net', - 'baseballmail.com', - 'basketballmail.com', - 'batuta.net', - 'baudoinconsulting.com', - 'bboy.zzn.com', - 'bcvibes.com', - 'beddly.com', - 'beeebank.com', - 'beenhad.com', - 'beep.ru', - 'beer.com', - 'beethoven.com', - 'belice.com', - 'belizehome.com', - 'bell.net', - 'bellair.net', - 'bellsouth.net', - 'berlin.com', - 'berlin.de', - 'berlinexpo.de', - 'bestmail.us', - 'betriebsdirektor.de', - 'bettergolf.net', - 'bharatmail.com', - 'big1.us', - 'bigassweb.com', - 'bigblue.net.au', - 'bigboab.com', - 'bigfoot.com', - 'bigfoot.de', - 'bigger.com', - 'biggerbadder.com', - 'bigmailbox.com', - 'bigmir.net', - 'bigpond.au', - 'bigpond.com', - 'bigpond.com.au', - 'bigpond.net', - 'bigpond.net.au', - 'bigramp.com', - 'bigstring.com', - 'bikemechanics.com', - 'bikeracer.com', - 'bikeracers.net', - 'bikerider.com', - 'billsfan.com', - 'billsfan.net', - 'bimla.net', - 'bin-wieder-da.de', - 'bio-muesli.info', - 'birdlover.com', - 'birdowner.net', - 'bisons.com', - 'bitmail.com', - 'bitpage.net', - 'bizhosting.com', - 'bk.ru', - 'blackburnmail.com', - 'blackplanet.com', - 'blader.com', - 'bladesmail.net', - 'blazemail.com', - 'bleib-bei-mir.de', - 'blockfilter.com', - 'blogmyway.org', - 'bluebottle.com', - 'bluehyppo.com', - 'bluemail.ch', - 'bluemail.dk', - 'bluesfan.com', - 'bluewin.ch', - 'blueyonder.co.uk', - 'blushmail.com', - 'blutig.me', - 'bmlsports.net', - 'boardermail.com', - 'boatracers.com', - 'bodhi.lawlita.com', - 'bol.com.br', - 'bolando.com', - 'bollywoodz.com', - 'boltonfans.com', - 'bombdiggity.com', - 'bonbon.net', - 'boom.com', - 'bootmail.com', - 'bootybay.de', - 'bornnaked.com', - 'bostonoffice.com', - 'boun.cr', - 'bounce.net', - 'bounces.amazon.com', - 'bouncr.com', - 'box.az', - 'box.ua', - 'boxbg.com', - 'boxemail.com', - 'boxformail.in', - 'boxfrog.com', - 'boximail.com', - 'boyzoneclub.com', - 'bradfordfans.com', - 'brasilia.net', - 'brazilmail.com', - 'brazilmail.com.br', - 'breadtimes.press', - 'breathe.com', - 'brennendesreich.de', - 'bresnan.net', - 'brew-master.com', - 'brew-meister.com', - 'brfree.com.br', - 'briefemail.com', - 'bright.net', - 'britneyclub.com', - 'brittonsign.com', - 'broadcast.net', - 'brokenvalve.com', - 'brusseler.com', - 'bsdmail.com', - 'btcmail.pw', - 'btconnect.co.uk', - 'btconnect.com', - 'btinternet.com', - 'btopenworld.co.uk', - 'buerotiger.de', - 'buffymail.com', - 'bullsfan.com', - 'bullsgame.com', - 'bumerang.ro', - 'bumpymail.com', - 'bund.us', - 'burnthespam.info', - 'burstmail.info', - 'buryfans.com', - 'business-man.com', - 'businessman.net', - 'busta-rhymes.com', - 'buyersusa.com', - 'bvimailbox.com', - 'byom.de', - 'c2.hu', - 'c2i.net', - 'c3.hu', - 'c4.com', - 'c51vsgq.com', - 'cabacabana.com', - 'cable.comcast.com', - 'cableone.net', - 'caere.it', - 'cairomail.com', - 'calendar-server.bounces.google.com', - 'calidifontain.be', - 'californiamail.com', - 'callnetuk.com', - 'callsign.net', - 'caltanet.it', - 'camidge.com', - 'canada-11.com', - 'canada.com', - 'canadianmail.com', - 'canoemail.com', - 'canwetalk.com', - 'caramail.com', - 'care2.com', - 'careerbuildermail.com', - 'carioca.net', - 'cartelera.org', - 'cartestraina.ro', - 'casablancaresort.com', - 'casema.nl', - 'cash4u.com', - 'cashette.com', - 'casino.com', - 'catcha.com', - 'catchamail.com', - 'catholic.org', - 'catlover.com', - 'cd2.com', - 'celineclub.com', - 'celtic.com', - 'center-mail.de', - 'centermail.at', - 'centermail.de', - 'centermail.info', - 'centoper.it', - 'centralpets.com', - 'centrum.cz', - 'centrum.sk', - 'centurytel.net', - 'certifiedmail.com', - 'cfl.rr.com', - 'cgac.es', - 'cghost.s-a-d.de', - 'chacuo.net', - 'chaiyomail.com', - 'chammy.info', - 'chance2mail.com', - 'chandrasekar.net', - 'charmedmail.com', - 'charter.net', - 'chat.ru', - 'chattown.com', - 'chauhanweb.com', - 'cheatmail.de', - 'chechnya.conf.work', - 'check.com', - 'check1check.com', - 'cheerful.com', - 'chef.net', - 'chek.com', - 'chello.nl', - 'chemist.com', - 'chequemail.com', - 'cheyenneweb.com', - 'chez.com', - 'chickmail.com', - 'china.com', - 'china.net.vg', - 'chinamail.com', - 'chirk.com', - 'chocaholic.com.au', - 'chong-mail.com', - 'chong-mail.net', - 'churchusa.com', - 'cia-agent.com', - 'cia.hu', - 'ciaoweb.it', - 'cicciociccio.com', - 'cincinow.net', - 'cinci.rr.com', - 'citiz.net', - 'citlink.net', - 'citromail.hu', - 'city-of-bath.org', - 'city-of-birmingham.com', - 'city-of-brighton.org', - 'city-of-cambridge.com', - 'city-of-coventry.com', - 'city-of-edinburgh.com', - 'city-of-lichfield.com', - 'city-of-lincoln.com', - 'city-of-liverpool.com', - 'city-of-manchester.com', - 'city-of-nottingham.com', - 'city-of-oxford.com', - 'city-of-swansea.com', - 'city-of-westminster.com', - 'city-of-westminster.net', - 'city-of-york.net', - 'cityofcardiff.net', - 'cityoflondon.org', - 'ckaazaza.tk', - 'claramail.com', - 'classicalfan.com', - 'classicmail.co.za', - 'clear.net.nz', - 'clearwire.net', - 'clerk.com', - 'cliffhanger.com', - 'clixser.com', - 'close2you.net', - 'clrmail.com', - 'club4x4.net', - 'clubalfa.com', - 'clubbers.net', - 'clubducati.com', - 'clubhonda.net', - 'clubmember.org', - 'clubnetnoir.com', - 'clubvdo.net', - 'cluemail.com', - 'cmail.net', - 'cmpmail.com', - 'cnnsimail.com', - 'cntv.cn', - 'codec.ro', - 'coder.hu', - 'coid.biz', - 'coldmail.com', - 'collectiblesuperstore.com', - 'collector.org', - 'collegeclub.com', - 'collegemail.com', - 'colleges.com', - 'columbus.rr.com', - 'columbusrr.com', - 'columnist.com', - 'comcast.net', - 'comic.com', - 'communityconnect.com', - 'comporium.net', - 'comprendemail.com', - 'compuserve.com', - 'computer-freak.com', - 'computer4u.com', - 'computermail.net', - 'conexcol.com', - 'conk.com', - 'connect4free.net', - 'connectbox.com', - 'consultant.com', - 'consumerriot.com', - 'contractor.net', - 'contrasto.cu.cc', - 'cookiemonster.com', - 'cool.br', - 'coole-files.de', - 'coolgoose.ca', - 'coolgoose.com', - 'coolkiwi.com', - 'coollist.com', - 'coolmail.com', - 'coolmail.net', - 'coolsend.com', - 'coolsite.net', - 'cooooool.com', - 'cooperation.net', - 'cooperationtogo.net', - 'copacabana.com', - 'copper.net', - 'cornells.com', - 'cornerpub.com', - 'corporatedirtbag.com', - 'correo.terra.com.gt', - 'cortinet.com', - 'cotas.net', - 'counsellor.com', - 'countrylover.com', - 'cox.com', - 'cox.net', - 'coxinet.net', - 'cracker.hu', - 'crapmail.org', - 'crazedanddazed.com', - 'crazymailing.com', - 'crazysexycool.com', - 'cristianemail.com', - 'critterpost.com', - 'croeso.com', - 'crosshairs.com', - 'crosswinds.net', - 'crwmail.com', - 'cry4helponline.com', - 'cs.com', - 'csinibaba.hu', - 'cuemail.com', - 'curio-city.com', - 'curryworld.de', - 'cute-girl.com', - 'cuteandcuddly.com', - 'cutey.com', - 'cww.de', - 'cyber-africa.net', - 'cyber-innovation.club', - 'cyber-matrix.com', - 'cyber-phone.eu', - 'cyber-wizard.com', - 'cyber4all.com', - 'cyberbabies.com', - 'cybercafemaui.com', - 'cyberdude.com', - 'cyberforeplay.net', - 'cybergal.com', - 'cybergrrl.com', - 'cyberinbox.com', - 'cyberleports.com', - 'cybermail.net', - 'cybernet.it', - 'cyberservices.com', - 'cyberspace-asia.com', - 'cybertrains.org', - 'cyclefanz.com', - 'cynetcity.com', - 'dabsol.net', - 'dadacasa.com', - 'daha.com', - 'dailypioneer.com', - 'dallasmail.com', - 'dangerous-minds.com', - 'dansegulvet.com', - 'dasdasdascyka.tk', - 'data54.com', - 'davegracey.com', - 'dawnsonmail.com', - 'dawsonmail.com', - 'dazedandconfused.com', - 'dbzmail.com', - 'dcemail.com', - 'deadlymob.org', - 'deagot.com', - 'deal-maker.com', - 'dearriba.com', - 'death-star.com', - 'deliveryman.com', - 'deneg.net', - 'depechemode.com', - 'deseretmail.com', - 'desertmail.com', - 'desilota.com', - 'deskpilot.com', - 'destin.com', - 'detik.com', - 'deutschland-net.com', - 'devotedcouples.com', - 'dezigner.ru', - 'dfwatson.com', - 'di-ve.com', - 'die-besten-bilder.de', - 'die-genossen.de', - 'die-optimisten.de', - 'die-optimisten.net', - 'diemailbox.de', - 'digibel.be', - 'digital-filestore.de', - 'diplomats.com', - 'directbox.com', - 'dirtracer.com', - 'discard.email', - 'discard.ga', - 'discard.gq', - 'disciples.com', - 'discofan.com', - 'discoverymail.com', - 'disign-concept.eu', - 'disign-revelation.com', - 'disinfo.net', - 'dispomail.eu', - 'disposable.com', - 'dispose.it', - 'dm.w3internet.co.uk', - 'dmailman.com', - 'dnainternet.net', - 'dnsmadeeasy.com', - 'doclist.bounces.google.com', - 'docmail.cz', - 'docs.google.com', - 'doctor.com', - 'dodgit.org', - 'dodo.com.au', - 'dodsi.com', - 'dog.com', - 'dogit.com', - 'doglover.com', - 'dogmail.co.uk', - 'dogsnob.net', - 'doityourself.com', - 'domforfb1.tk', - 'domforfb2.tk', - 'domforfb3.tk', - 'domforfb4.tk', - 'domforfb5.tk', - 'domforfb6.tk', - 'domforfb7.tk', - 'domforfb8.tk', - 'domozmail.com', - 'doneasy.com', - 'donjuan.com', - 'dontgotmail.com', - 'dontmesswithtexas.com', - 'doramail.com', - 'dostmail.com', - 'dotcom.fr', - 'dotmsg.com', - 'dott.it', - 'download-privat.de', - 'dplanet.ch', - 'dr.com', - 'dragoncon.net', - 'dropmail.me', - 'dropzone.com', - 'drotposta.hu', - 'dubaimail.com', - 'dublin.com', - 'dublin.ie', - 'duck.com', - 'dumpmail.com', - 'dumpmail.de', - 'dumpyemail.com', - 'dunlopdriver.com', - 'dunloprider.com', - 'duno.com', - 'duskmail.com', - 'dutchmail.com', - 'dwp.net', - 'dygo.com', - 'dynamitemail.com', - 'dyndns.org', - 'e-apollo.lv', - 'e-mail.com.tr', - 'e-mail.dk', - 'e-mail.ru', - 'e-mail.ua', - 'e-mailanywhere.com', - 'e-mails.ru', - 'e-tapaal.com', - 'earthalliance.com', - 'earthcam.net', - 'earthdome.com', - 'earthling.net', - 'earthlink.net', - 'earthonline.net', - 'eastcoast.co.za', - 'eastmail.com', - 'easy.to', - 'easypost.com', - 'easytrashmail.com', - 'ec.rr.com', - 'ecardmail.com', - 'ecbsolutions.net', - 'echina.com', - 'ecolo-online.fr', - 'ecompare.com', - 'edmail.com', - 'ednatx.com', - 'edtnmail.com', - 'educacao.te.pt', - 'eelmail.com', - 'ehmail.com', - 'einrot.com', - 'einrot.de', - 'eintagsmail.de', - 'eircom.net', - 'elisanet.fi', - 'elitemail.org', - 'elsitio.com', - 'elvis.com', - 'elvisfan.com', - 'email-fake.gq', - 'email-london.co.uk', - 'email.biz', - 'email.cbes.net', - 'email.com', - 'email.cz', - 'email.ee', - 'email.it', - 'email.nu', - 'email.org', - 'email.ro', - 'email.ru', - 'email.si', - 'email.su', - 'email.ua', - 'email2me.net', - 'email4u.info', - 'emailacc.com', - 'emailaccount.com', - 'emailage.ga', - 'emailage.gq', - 'emailasso.net', - 'emailchoice.com', - 'emailcorner.net', - 'emailem.com', - 'emailengine.net', - 'emailengine.org', - 'emailer.hubspot.com', - 'emailforyou.net', - 'emailgo.de', - 'emailgroups.net', - 'emailinfive.com', - 'emailit.com', - 'emailpinoy.com', - 'emailplanet.com', - 'emailplus.org', - 'emailproxsy.com', - 'emails.ga', - 'emails.incisivemedia.com', - 'emails.ru', - 'emailthe.net', - 'emailto.de', - 'emailuser.net', - 'emailx.net', - 'emailz.ga', - 'emailz.gq', - 'ematic.com', - 'embarqmail.com', - 'emeil.in', - 'emeil.ir', - 'emil.com', - 'eml.cc', - 'eml.pp.ua', - 'end-war.com', - 'enel.net', - 'engineer.com', - 'england.com', - 'england.edu', - 'englandmail.com', - 'epage.ru', - 'epatra.com', - 'ephemail.net', - 'epix.net', - 'epost.de', - 'eposta.hu', - 'eqqu.com', - 'eramail.co.za', - 'eresmas.com', - 'eriga.lv', - 'estranet.it', - 'ethos.st', - 'etoast.com', - 'etrademail.com', - 'etranquil.com', - 'etranquil.net', - 'eudoramail.com', - 'europamel.net', - 'europe.com', - 'europemail.com', - 'euroseek.com', - 'eurosport.com', - 'every1.net', - 'everyday.com.kh', - 'everymail.net', - 'everyone.net', - 'everytg.ml', - 'examnotes.net', - 'excite.co.jp', - 'excite.com', - 'excite.it', - 'execs.com', - 'exemail.com.au', - 'exg6.exghost.com', - 'existiert.net', - 'expressasia.com', - 'extenda.net', - 'extended.com', - 'eyepaste.com', - 'eyou.com', - 'ezcybersearch.com', - 'ezmail.egine.com', - 'ezmail.ru', - 'ezrs.com', - 'f-m.fm', - 'f1fans.net', - 'facebook-email.ga', - 'facebook.com', - 'facebookmail.com', - 'facebookmail.gq', - 'fahr-zur-hoelle.org', - 'fake-email.pp.ua', - 'fake-mail.cf', - 'fake-mail.ga', - 'fake-mail.ml', - 'fakemailz.com', - 'falseaddress.com', - 'fan.com', - 'fansonlymail.com', - 'fansworldwide.de', - 'fantasticmail.com', - 'farang.net', - 'farifluset.mailexpire.com', - 'faroweb.com', - 'fast-email.com', - 'fast-mail.fr', - 'fast-mail.org', - 'fastacura.com', - 'fastchevy.com', - 'fastchrysler.com', - 'fastem.com', - 'fastemail.us', - 'fastemailer.com', - 'fastermail.com', - 'fastest.cc', - 'fastimap.com', - 'fastkawasaki.com', - 'fastmail.ca', - 'fastmail.cn', - 'fastmail.co.uk', - 'fastmail.com', - 'fastmail.com.au', - 'fastmail.es', - 'fastmail.fm', - 'fastmail.im', - 'fastmail.in', - 'fastmail.jp', - 'fastmail.mx', - 'fastmail.net', - 'fastmail.nl', - 'fastmail.se', - 'fastmail.to', - 'fastmail.tw', - 'fastmail.us', - 'fastmailbox.net', - 'fastmazda.com', - 'fastmessaging.com', - 'fastmitsubishi.com', - 'fastnissan.com', - 'fastservice.com', - 'fastsubaru.com', - 'fastsuzuki.com', - 'fasttoyota.com', - 'fastyamaha.com', - 'fatcock.net', - 'fatflap.com', - 'fathersrightsne.org', - 'fax.ru', - 'fbi-agent.com', - 'fbi.hu', - 'fdfdsfds.com', - 'fea.st', - 'federalcontractors.com', - 'feinripptraeger.de', - 'felicitymail.com', - 'femenino.com', - 'fetchmail.co.uk', - 'fettabernett.de', - 'feyenoorder.com', - 'ffanet.com', - 'fiberia.com', - 'ficken.de', - 'fightallspam.com', - 'filipinolinks.com', - 'financemail.net', - 'financier.com', - 'findmail.com', - 'finebody.com', - 'fire-brigade.com', - 'fireman.net', - 'fishburne.org', - 'fishfuse.com', - 'fixmail.tk', - 'fizmail.com', - 'flashbox.5july.org', - 'flashmail.com', - 'flashmail.net', - 'fleckens.hu', - 'flipcode.com', - 'fmail.co.uk', - 'fmailbox.com', - 'fmgirl.com', - 'fmguy.com', - 'fnbmail.co.za', - 'fnmail.com', - 'folkfan.com', - 'foodmail.com', - 'footard.com', - 'footballmail.com', - 'foothills.net', - 'for-president.com', - 'force9.co.uk', - 'forfree.at', - 'forgetmail.com', - 'fornow.eu', - 'forpresident.com', - 'fortuncity.com', - 'fortunecity.com', - 'forum.dk', - 'foxmail.com', - 'fr33mail.info', - 'francemel.fr', - 'free-email.ga', - 'free-online.net', - 'free-org.com', - 'free.com.pe', - 'free.fr', - 'freeaccess.nl', - 'freeaccount.com', - 'freeandsingle.com', - 'freedom.usa.com', - 'freedomlover.com', - 'freegates.be', - 'freeghana.com', - 'freelance-france.eu', - 'freeler.nl', - 'freemail.c3.hu', - 'freemail.com.au', - 'freemail.com.pk', - 'freemail.de', - 'freemail.et', - 'freemail.gr', - 'freemail.hu', - 'freemail.it', - 'freemail.lt', - 'freemail.ms', - 'freemail.nl', - 'freemail.org.mk', - 'freemails.ga', - 'freemeil.gq', - 'freenet.de', - 'freenet.kg', - 'freeola.com', - 'freeola.net', - 'freeserve.co.uk', - 'freestart.hu', - 'freesurf.fr', - 'freesurf.nl', - 'freeuk.com', - 'freeuk.net', - 'freeukisp.co.uk', - 'freeweb.org', - 'freewebemail.com', - 'freeyellow.com', - 'freezone.co.uk', - 'fresnomail.com', - 'freudenkinder.de', - 'freundin.ru', - 'friendlymail.co.uk', - 'friends-cafe.com', - 'friendsfan.com', - 'from-africa.com', - 'from-america.com', - 'from-argentina.com', - 'from-asia.com', - 'from-australia.com', - 'from-belgium.com', - 'from-brazil.com', - 'from-canada.com', - 'from-china.net', - 'from-england.com', - 'from-europe.com', - 'from-france.net', - 'from-germany.net', - 'from-holland.com', - 'from-israel.com', - 'from-italy.net', - 'from-japan.net', - 'from-korea.com', - 'from-mexico.com', - 'from-outerspace.com', - 'from-russia.com', - 'from-spain.net', - 'fromalabama.com', - 'fromalaska.com', - 'fromarizona.com', - 'fromarkansas.com', - 'fromcalifornia.com', - 'fromcolorado.com', - 'fromconnecticut.com', - 'fromdelaware.com', - 'fromflorida.net', - 'fromgeorgia.com', - 'fromhawaii.net', - 'fromidaho.com', - 'fromillinois.com', - 'fromindiana.com', - 'fromiowa.com', - 'fromjupiter.com', - 'fromkansas.com', - 'fromkentucky.com', - 'fromlouisiana.com', - 'frommaine.net', - 'frommaryland.com', - 'frommassachusetts.com', - 'frommiami.com', - 'frommichigan.com', - 'fromminnesota.com', - 'frommississippi.com', - 'frommissouri.com', - 'frommontana.com', - 'fromnebraska.com', - 'fromnevada.com', - 'fromnewhampshire.com', - 'fromnewjersey.com', - 'fromnewmexico.com', - 'fromnewyork.net', - 'fromnorthcarolina.com', - 'fromnorthdakota.com', - 'fromohio.com', - 'fromoklahoma.com', - 'fromoregon.net', - 'frompennsylvania.com', - 'fromrhodeisland.com', - 'fromru.com', - 'fromsouthcarolina.com', - 'fromsouthdakota.com', - 'fromtennessee.com', - 'fromtexas.com', - 'fromthestates.com', - 'fromutah.com', - 'fromvermont.com', - 'fromvirginia.com', - 'fromwashington.com', - 'fromwashingtondc.com', - 'fromwestvirginia.com', - 'fromwisconsin.com', - 'fromwyoming.com', - 'front.ru', - 'frontier.com', - 'frontiernet.net', - 'frostbyte.uk.net', - 'fsmail.net', - 'ftc-i.net', - 'ftml.net', - 'fullmail.com', - 'funkfan.com', - 'fuorissimo.com', - 'furnitureprovider.com', - 'fuse.net', - 'fut.es', - 'fux0ringduh.com', - 'fwnb.com', - 'fxsmails.com', - 'galaxy5.com', - 'galaxyhit.com', - 'gamebox.net', - 'gamegeek.com', - 'gamespotmail.com', - 'gamno.config.work', - 'garbage.com', - 'gardener.com', - 'gawab.com', - 'gaybrighton.co.uk', - 'gaza.net', - 'gazeta.pl', - 'gazibooks.com', - 'gci.net', - 'geecities.com', - 'geek.com', - 'geek.hu', - 'geeklife.com', - 'gelitik.in', - 'gencmail.com', - 'general-hospital.com', - 'gentlemansclub.de', - 'geocities.com', - 'geography.net', - 'geologist.com', - 'geopia.com', - 'germanymail.com', - 'get.pp.ua', - 'get1mail.com', - 'getairmail.cf', - 'getairmail.com', - 'getairmail.ga', - 'getairmail.gq', - 'getonemail.net', - 'ghanamail.com', - 'ghostmail.com', - 'ghosttexter.de', - 'giga4u.de', - 'gigileung.org', - 'girl4god.com', - 'givepeaceachance.com', - 'glay.org', - 'glendale.net', - 'globalfree.it', - 'globalpagan.com', - 'globalsite.com.br', - 'gmail.com', - 'gmail.com.br', - 'gmail.ru', - 'gmx.at', - 'gmx.ch', - 'gmx.com', - 'gmx.de', - 'gmx.li', - 'gmx.net', - 'go.com', - 'go.ro', - 'go.ru', - 'go2net.com', - 'gocollege.com', - 'gocubs.com', - 'goemailgo.com', - 'gofree.co.uk', - 'gol.com', - 'goldenmail.ru', - 'goldmail.ru', - 'goldtoolbox.com', - 'golfemail.com', - 'golfilla.info', - 'golfmail.be', - 'gonavy.net', - 'goodnewsmail.com', - 'goodstick.com', - 'googlegroups.com', - 'googlemail.com', - 'goplay.com', - 'gorillaswithdirtyarmpits.com', - 'gorontalo.net', - 'gospelfan.com', - 'gothere.uk.com', - 'gotmail.com', - 'gotmail.org', - 'gotomy.com', - 'gotti.otherinbox.com', - 'gportal.hu', - 'graduate.org', - 'graffiti.net', - 'gramszu.net', - 'grandmamail.com', - 'grandmasmail.com', - 'graphic-designer.com', - 'grapplers.com', - 'gratisweb.com', - 'greenmail.net', - 'groupmail.com', - 'grr.la', - 'grungecafe.com', - 'gtmc.net', - 'gua.net', - 'guessmail.com', - 'guju.net', - 'gustr.com', - 'guy.com', - 'guy2.com', - 'guyanafriends.com', - 'gyorsposta.com', - 'gyorsposta.hu', - 'h-mail.us', - 'hab-verschlafen.de', - 'habmalnefrage.de', - 'hacccc.com', - 'hackermail.com', - 'hackermail.net', - 'hailmail.net', - 'hairdresser.net', - 'hamptonroads.com', - 'handbag.com', - 'handleit.com', - 'hang-ten.com', - 'hanmail.net', - 'happemail.com', - 'happycounsel.com', - 'happypuppy.com', - 'harakirimail.com', - 'hardcorefreak.com', - 'hartbot.de', - 'hawaii.rr.com', - 'hawaiiantel.net', - 'heartthrob.com', - 'heerschap.com', - 'heesun.net', - 'hehe.com', - 'hello.hu', - 'hello.net.au', - 'hello.to', - 'helter-skelter.com', - 'herediano.com', - 'herono1.com', - 'herp.in', - 'herr-der-mails.de', - 'hetnet.nl', - 'hey.to', - 'hhdevel.com', - 'hidzz.com', - 'highmilton.com', - 'highquality.com', - 'highveldmail.co.za', - 'hilarious.com', - 'hiphopfan.com', - 'hispavista.com', - 'hitmail.com', - 'hitthe.net', - 'hkg.net', - 'hkstarphoto.com', - 'hockeymail.com', - 'hollywoodkids.com', - 'home-email.com', - 'home.de', - 'home.nl', - 'home.no.net', - 'home.ro', - 'home.se', - 'homelocator.com', - 'homemail.com', - 'homestead.com', - 'honduras.com', - 'hongkong.com', - 'hookup.net', - 'hoopsmail.com', - 'hopemail.biz', - 'horrormail.com', - 'hot-mail.gq', - 'hot-shot.com', - 'hot.ee', - 'hotbot.com', - 'hotbrev.com', - 'hotfire.net', - 'hotletter.com', - 'hotmail.ca', - 'hotmail.ch', - 'hotmail.co', - 'hotmail.co.il', - 'hotmail.co.jp', - 'hotmail.co.nz', - 'hotmail.co.uk', - 'hotmail.co.za', - 'hotmail.com', - 'hotmail.com.au', - 'hotmail.com.br', - 'hotmail.com.tr', - 'hotmail.de', - 'hotmail.es', - 'hotmail.fi', - 'hotmail.fr', - 'hotmail.it', - 'hotmail.kg', - 'hotmail.kz', - 'hotmail.nl', - 'hotmail.ru', - 'hotmail.se', - 'hotpop.com', - 'hotpop3.com', - 'hotvoice.com', - 'housemail.com', - 'hsuchi.net', - 'hu2.ru', - 'hughes.net', - 'humanoid.net', - 'humn.ws.gy', - 'hunsa.com', - 'hurting.com', - 'hush.com', - 'hushmail.com', - 'hypernautica.com', - 'i-connect.com', - 'i-france.com', - 'i-mail.com.au', - 'i-p.com', - 'i.am', - 'i.ua', - 'i12.com', - 'i2pmail.org', - 'iamawoman.com', - 'iamwaiting.com', - 'iamwasted.com', - 'iamyours.com', - 'icestorm.com', - 'ich-bin-verrueckt-nach-dir.de', - 'ich-will-net.de', - 'icloud.com', - 'icmsconsultants.com', - 'icq.com', - 'icqmail.com', - 'icrazy.com', - 'id-base.com', - 'ididitmyway.com', - 'idigjesus.com', - 'idirect.com', - 'ieatspam.eu', - 'ieatspam.info', - 'ieh-mail.de', - 'iespana.es', - 'ifoward.com', - 'ig.com.br', - 'ignazio.it', - 'ignmail.com', - 'ihateclowns.com', - 'ihateyoualot.info', - 'iheartspam.org', - 'iinet.net.au', - 'ijustdontcare.com', - 'ikbenspamvrij.nl', - 'ilkposta.com', - 'ilovechocolate.com', - 'ilovejesus.com', - 'ilovetocollect.net', - 'ilse.nl', - 'imaginemail.com', - 'imail.ru', - 'imailbox.com', - 'imap-mail.com', - 'imap.cc', - 'imapmail.org', - 'imel.org', - 'imgof.com', - 'imgv.de', - 'immo-gerance.info', - 'imneverwrong.com', - 'imposter.co.uk', - 'imstations.com', - 'imstressed.com', - 'imtoosexy.com', - 'in-box.net', - 'in2jesus.com', - 'iname.com', - 'inbax.tk', - 'inbound.plus', - 'inbox.com', - 'inbox.net', - 'inbox.ru', - 'inbox.si', - 'inboxalias.com', - 'incamail.com', - 'incredimail.com', - 'indeedemail.com', - 'index.ua', - 'indexa.fr', - 'india.com', - 'indiatimes.com', - 'indo-mail.com', - 'indocities.com', - 'indomail.com', - 'indyracers.com', - 'inerted.com', - 'inet.com', - 'inet.net.au', - 'info-media.de', - 'info-radio.ml', - 'info66.com', - 'infohq.com', - 'infomail.es', - 'infomart.or.jp', - 'infospacemail.com', - 'infovia.com.ar', - 'inicia.es', - 'inmail.sk', - 'inmail24.com', - 'inmano.com', - 'inmynetwork.tk', - 'innocent.com', - 'inorbit.com', - 'inoutbox.com', - 'insidebaltimore.net', - 'insight.rr.com', - 'instant-mail.de', - 'instantemailaddress.com', - 'instantmail.fr', - 'instruction.com', - 'instructor.net', - 'insurer.com', - 'interburp.com', - 'interfree.it', - 'interia.pl', - 'interlap.com.ar', - 'intermail.co.il', - 'internet-e-mail.com', - 'internet-mail.org', - 'internet-police.com', - 'internetbiz.com', - 'internetdrive.com', - 'internetegypt.com', - 'internetemails.net', - 'internetmailing.net', - 'internode.on.net', - 'invalid.com', - 'inwind.it', - 'iobox.com', - 'iobox.fi', - 'iol.it', - 'iol.pt', - 'iowaemail.com', - 'ip3.com', - 'ip4.pp.ua', - 'ip6.pp.ua', - 'ipoo.org', - 'iprimus.com.au', - 'iqemail.com', - 'irangate.net', - 'iraqmail.com', - 'ireland.com', - 'irelandmail.com', - 'iremail.de', - 'irj.hu', - 'iroid.com', - 'isellcars.com', - 'iservejesus.com', - 'islamonline.net', - 'isleuthmail.com', - 'ismart.net', - 'isonfire.com', - 'isp9.net', - 'israelmail.com', - 'ist-allein.info', - 'ist-einmalig.de', - 'ist-ganz-allein.de', - 'ist-willig.de', - 'italymail.com', - 'itloox.com', - 'itmom.com', - 'ivebeenframed.com', - 'ivillage.com', - 'iwan-fals.com', - 'iwmail.com', - 'iwon.com', - 'izadpanah.com', - 'jahoopa.com', - 'jakuza.hu', - 'japan.com', - 'jaydemail.com', - 'jazzandjava.com', - 'jazzfan.com', - 'jazzgame.com', - 'je-recycle.info', - 'jerusalemmail.com', - 'jet-renovation.fr', - 'jetable.de', - 'jetable.pp.ua', - 'jetemail.net', - 'jippii.fi', - 'jmail.co.za', - 'job4u.com', - 'jobbikszimpatizans.hu', - 'joelonsoftware.com', - 'joinme.com', - 'jokes.com', - 'jordanmail.com', - 'journalist.com', - 'jourrapide.com', - 'jovem.te.pt', - 'joymail.com', - 'jpopmail.com', - 'jsrsolutions.com', - 'jubiimail.dk', - 'jump.com', - 'jumpy.it', - 'juniormail.com', - 'junk1e.com', - 'junkmail.com', - 'junkmail.gq', - 'juno.com', - 'justemail.net', - 'justicemail.com', - 'kaazoo.com', - 'kaffeeschluerfer.com', - 'kaffeeschluerfer.de', - 'kaixo.com', - 'kalpoint.com', - 'kansascity.com', - 'kapoorweb.com', - 'karachian.com', - 'karachioye.com', - 'karbasi.com', - 'katamail.com', - 'kayafmmail.co.za', - 'kbjrmail.com', - 'kcks.com', - 'keg-party.com', - 'keinpardon.de', - 'keko.com.ar', - 'kellychen.com', - 'keromail.com', - 'keyemail.com', - 'kgb.hu', - 'khosropour.com', - 'kickassmail.com', - 'killermail.com', - 'kimo.com', - 'kimsdisk.com', - 'kinglibrary.net', - 'kinki-kids.com', - 'kissfans.com', - 'kittymail.com', - 'kitznet.at', - 'kiwibox.com', - 'kiwitown.com', - 'klassmaster.net', - 'km.ru', - 'knol-power.nl', - 'kolumbus.fi', - 'kommespaeter.de', - 'konx.com', - 'korea.com', - 'koreamail.com', - 'kpnmail.nl', - 'krim.ws', - 'krongthip.com', - 'krunis.com', - 'ksanmail.com', - 'ksee24mail.com', - 'kube93mail.com', - 'kukamail.com', - 'kulturbetrieb.info', - 'kumarweb.com', - 'kuwait-mail.com', - 'l33r.eu', - 'la.com', - 'labetteraverouge.at', - 'ladymail.cz', - 'lagerlouts.com', - 'lags.us', - 'lahoreoye.com', - 'lakmail.com', - 'lamer.hu', - 'land.ru', - 'lankamail.com', - 'laoeq.com', - 'laposte.net', - 'lass-es-geschehen.de', - 'last-chance.pro', - 'lastmail.co', - 'latemodels.com', - 'latinmail.com', - 'lavache.com', - 'law.com', - 'lawyer.com', - 'lazyinbox.com', - 'leehom.net', - 'legalactions.com', - 'legalrc.loan', - 'legislator.com', - 'lenta.ru', - 'leonlai.net', - 'letsgomets.net', - 'letterboxes.org', - 'letthemeatspam.com', - 'levele.com', - 'levele.hu', - 'lex.bg', - 'lexis-nexis-mail.com', - 'libero.it', - 'liberomail.com', - 'lick101.com', - 'liebt-dich.info', - 'linkmaster.com', - 'linktrader.com', - 'linuxfreemail.com', - 'linuxmail.org', - 'lionsfan.com.au', - 'liontrucks.com', - 'liquidinformation.net', - 'list.ru', - 'listomail.com', - 'littleapple.com', - 'littleblueroom.com', - 'live.at', - 'live.be', - 'live.ca', - 'live.cl', - 'live.cn', - 'live.co.uk', - 'live.co.za', - 'live.com', - 'live.com.ar', - 'live.com.au', - 'live.com.mx', - 'live.com.pt', - 'live.com.sg', - 'live.de', - 'live.dk', - 'live.fr', - 'live.ie', - 'live.in', - 'live.it', - 'live.jp', - 'live.nl', - 'live.no', - 'live.ru', - 'live.se', - 'liveradio.tk', - 'liverpoolfans.com', - 'llandudno.com', - 'llangollen.com', - 'lmxmail.sk', - 'lobbyist.com', - 'localbar.com', - 'locos.com', - 'login-email.ga', - 'loh.pp.ua', - 'lolfreak.net', - 'lolito.tk', - 'london.com', - 'looksmart.co.uk', - 'looksmart.com', - 'looksmart.com.au', - 'lopezclub.com', - 'louiskoo.com', - 'love.cz', - 'loveable.com', - 'lovecat.com', - 'lovefall.ml', - 'lovefootball.com', - 'lovelygirl.net', - 'lovemail.com', - 'lover-boy.com', - 'lovergirl.com', - 'lovesea.gq', - 'lovethebroncos.com', - 'lovethecowboys.com', - 'loveyouforever.de', - 'lovingjesus.com', - 'lowandslow.com', - 'lr7.us', - 'lroid.com', - 'luso.pt', - 'luukku.com', - 'luv2.us', - 'lvie.com.sg', - 'lycos.co.uk', - 'lycos.com', - 'lycos.es', - 'lycos.it', - 'lycos.ne.jp', - 'lycosmail.com', - 'm-a-i-l.com', - 'm-hmail.com', - 'm4.org', - 'm4ilweb.info', - 'mac.com', - 'macbox.com', - 'macfreak.com', - 'machinecandy.com', - 'macmail.com', - 'madcreations.com', - 'madonnafan.com', - 'madrid.com', - 'maennerversteherin.com', - 'maennerversteherin.de', - 'maffia.hu', - 'magicmail.co.za', - 'magspam.net', - 'mahmoodweb.com', - 'mail.bg', - 'mail-awu.de', - 'mail-box.cz', - 'mail-center.com', - 'mail-central.com', - 'mail-easy.fr', - 'mail-filter.com', - 'mail-me.com', - 'mail-page.com', - 'mail-tester.com', - 'mail.austria.com', - 'mail.az', - 'mail.be', - 'mail.bulgaria.com', - 'mail.by', - 'mail.co.za', - 'mail.com', - 'mail.com.tr', - 'mail.de', - 'mail.ee', - 'mail.entrepeneurmag.com', - 'mail.freetown.com', - 'mail.gr', - 'mail.hitthebeach.com', - 'mail.htl22.at', - 'mail.md', - 'mail.misterpinball.de', - 'mail.nu', - 'mail.org.uk', - 'mail.pf', - 'mail.pt', - 'mail.r-o-o-t.com', - 'mail.ru', - 'mail.sisna.com', - 'mail.svenz.eu', - 'mail.usa.com', - 'mail.vasarhely.hu', - 'mail.wtf', - 'mail114.net', - 'mail15.com', - 'mail2007.com', - 'mail2aaron.com', - 'mail2abby.com', - 'mail2abc.com', - 'mail2actor.com', - 'mail2admiral.com', - 'mail2adorable.com', - 'mail2adoration.com', - 'mail2adore.com', - 'mail2adventure.com', - 'mail2aeolus.com', - 'mail2aether.com', - 'mail2affection.com', - 'mail2afghanistan.com', - 'mail2africa.com', - 'mail2agent.com', - 'mail2aha.com', - 'mail2ahoy.com', - 'mail2aim.com', - 'mail2air.com', - 'mail2airbag.com', - 'mail2airforce.com', - 'mail2airport.com', - 'mail2alabama.com', - 'mail2alan.com', - 'mail2alaska.com', - 'mail2albania.com', - 'mail2alcoholic.com', - 'mail2alec.com', - 'mail2alexa.com', - 'mail2algeria.com', - 'mail2alicia.com', - 'mail2alien.com', - 'mail2allan.com', - 'mail2allen.com', - 'mail2allison.com', - 'mail2alpha.com', - 'mail2alyssa.com', - 'mail2amanda.com', - 'mail2amazing.com', - 'mail2amber.com', - 'mail2america.com', - 'mail2american.com', - 'mail2andorra.com', - 'mail2andrea.com', - 'mail2andy.com', - 'mail2anesthesiologist.com', - 'mail2angela.com', - 'mail2angola.com', - 'mail2ann.com', - 'mail2anna.com', - 'mail2anne.com', - 'mail2anthony.com', - 'mail2anything.com', - 'mail2aphrodite.com', - 'mail2apollo.com', - 'mail2april.com', - 'mail2aquarius.com', - 'mail2arabia.com', - 'mail2arabic.com', - 'mail2architect.com', - 'mail2ares.com', - 'mail2argentina.com', - 'mail2aries.com', - 'mail2arizona.com', - 'mail2arkansas.com', - 'mail2armenia.com', - 'mail2army.com', - 'mail2arnold.com', - 'mail2art.com', - 'mail2artemus.com', - 'mail2arthur.com', - 'mail2artist.com', - 'mail2ashley.com', - 'mail2ask.com', - 'mail2astronomer.com', - 'mail2athena.com', - 'mail2athlete.com', - 'mail2atlas.com', - 'mail2atom.com', - 'mail2attitude.com', - 'mail2auction.com', - 'mail2aunt.com', - 'mail2australia.com', - 'mail2austria.com', - 'mail2azerbaijan.com', - 'mail2baby.com', - 'mail2bahamas.com', - 'mail2bahrain.com', - 'mail2ballerina.com', - 'mail2ballplayer.com', - 'mail2band.com', - 'mail2bangladesh.com', - 'mail2bank.com', - 'mail2banker.com', - 'mail2bankrupt.com', - 'mail2baptist.com', - 'mail2bar.com', - 'mail2barbados.com', - 'mail2barbara.com', - 'mail2barter.com', - 'mail2basketball.com', - 'mail2batter.com', - 'mail2beach.com', - 'mail2beast.com', - 'mail2beatles.com', - 'mail2beauty.com', - 'mail2becky.com', - 'mail2beijing.com', - 'mail2belgium.com', - 'mail2belize.com', - 'mail2ben.com', - 'mail2bernard.com', - 'mail2beth.com', - 'mail2betty.com', - 'mail2beverly.com', - 'mail2beyond.com', - 'mail2biker.com', - 'mail2bill.com', - 'mail2billionaire.com', - 'mail2billy.com', - 'mail2bio.com', - 'mail2biologist.com', - 'mail2black.com', - 'mail2blackbelt.com', - 'mail2blake.com', - 'mail2blind.com', - 'mail2blonde.com', - 'mail2blues.com', - 'mail2bob.com', - 'mail2bobby.com', - 'mail2bolivia.com', - 'mail2bombay.com', - 'mail2bonn.com', - 'mail2bookmark.com', - 'mail2boreas.com', - 'mail2bosnia.com', - 'mail2boston.com', - 'mail2botswana.com', - 'mail2bradley.com', - 'mail2brazil.com', - 'mail2breakfast.com', - 'mail2brian.com', - 'mail2bride.com', - 'mail2brittany.com', - 'mail2broker.com', - 'mail2brook.com', - 'mail2bruce.com', - 'mail2brunei.com', - 'mail2brunette.com', - 'mail2brussels.com', - 'mail2bryan.com', - 'mail2bug.com', - 'mail2bulgaria.com', - 'mail2business.com', - 'mail2buy.com', - 'mail2ca.com', - 'mail2california.com', - 'mail2calvin.com', - 'mail2cambodia.com', - 'mail2cameroon.com', - 'mail2canada.com', - 'mail2cancer.com', - 'mail2capeverde.com', - 'mail2capricorn.com', - 'mail2cardinal.com', - 'mail2cardiologist.com', - 'mail2care.com', - 'mail2caroline.com', - 'mail2carolyn.com', - 'mail2casey.com', - 'mail2cat.com', - 'mail2caterer.com', - 'mail2cathy.com', - 'mail2catlover.com', - 'mail2catwalk.com', - 'mail2cell.com', - 'mail2chad.com', - 'mail2champaign.com', - 'mail2charles.com', - 'mail2chef.com', - 'mail2chemist.com', - 'mail2cherry.com', - 'mail2chicago.com', - 'mail2chile.com', - 'mail2china.com', - 'mail2chinese.com', - 'mail2chocolate.com', - 'mail2christian.com', - 'mail2christie.com', - 'mail2christmas.com', - 'mail2christy.com', - 'mail2chuck.com', - 'mail2cindy.com', - 'mail2clark.com', - 'mail2classifieds.com', - 'mail2claude.com', - 'mail2cliff.com', - 'mail2clinic.com', - 'mail2clint.com', - 'mail2close.com', - 'mail2club.com', - 'mail2coach.com', - 'mail2coastguard.com', - 'mail2colin.com', - 'mail2college.com', - 'mail2colombia.com', - 'mail2color.com', - 'mail2colorado.com', - 'mail2columbia.com', - 'mail2comedian.com', - 'mail2composer.com', - 'mail2computer.com', - 'mail2computers.com', - 'mail2concert.com', - 'mail2congo.com', - 'mail2connect.com', - 'mail2connecticut.com', - 'mail2consultant.com', - 'mail2convict.com', - 'mail2cook.com', - 'mail2cool.com', - 'mail2cory.com', - 'mail2costarica.com', - 'mail2country.com', - 'mail2courtney.com', - 'mail2cowboy.com', - 'mail2cowgirl.com', - 'mail2craig.com', - 'mail2crave.com', - 'mail2crazy.com', - 'mail2create.com', - 'mail2croatia.com', - 'mail2cry.com', - 'mail2crystal.com', - 'mail2cuba.com', - 'mail2culture.com', - 'mail2curt.com', - 'mail2customs.com', - 'mail2cute.com', - 'mail2cutey.com', - 'mail2cynthia.com', - 'mail2cyprus.com', - 'mail2czechrepublic.com', - 'mail2dad.com', - 'mail2dale.com', - 'mail2dallas.com', - 'mail2dan.com', - 'mail2dana.com', - 'mail2dance.com', - 'mail2dancer.com', - 'mail2danielle.com', - 'mail2danny.com', - 'mail2darlene.com', - 'mail2darling.com', - 'mail2darren.com', - 'mail2daughter.com', - 'mail2dave.com', - 'mail2dawn.com', - 'mail2dc.com', - 'mail2dealer.com', - 'mail2deanna.com', - 'mail2dearest.com', - 'mail2debbie.com', - 'mail2debby.com', - 'mail2deer.com', - 'mail2delaware.com', - 'mail2delicious.com', - 'mail2demeter.com', - 'mail2democrat.com', - 'mail2denise.com', - 'mail2denmark.com', - 'mail2dennis.com', - 'mail2dentist.com', - 'mail2derek.com', - 'mail2desert.com', - 'mail2devoted.com', - 'mail2devotion.com', - 'mail2diamond.com', - 'mail2diana.com', - 'mail2diane.com', - 'mail2diehard.com', - 'mail2dilemma.com', - 'mail2dillon.com', - 'mail2dinner.com', - 'mail2dinosaur.com', - 'mail2dionysos.com', - 'mail2diplomat.com', - 'mail2director.com', - 'mail2dirk.com', - 'mail2disco.com', - 'mail2dive.com', - 'mail2diver.com', - 'mail2divorced.com', - 'mail2djibouti.com', - 'mail2doctor.com', - 'mail2doglover.com', - 'mail2dominic.com', - 'mail2dominica.com', - 'mail2dominicanrepublic.com', - 'mail2don.com', - 'mail2donald.com', - 'mail2donna.com', - 'mail2doris.com', - 'mail2dorothy.com', - 'mail2doug.com', - 'mail2dough.com', - 'mail2douglas.com', - 'mail2dow.com', - 'mail2downtown.com', - 'mail2dream.com', - 'mail2dreamer.com', - 'mail2dude.com', - 'mail2dustin.com', - 'mail2dyke.com', - 'mail2dylan.com', - 'mail2earl.com', - 'mail2earth.com', - 'mail2eastend.com', - 'mail2eat.com', - 'mail2economist.com', - 'mail2ecuador.com', - 'mail2eddie.com', - 'mail2edgar.com', - 'mail2edwin.com', - 'mail2egypt.com', - 'mail2electron.com', - 'mail2eli.com', - 'mail2elizabeth.com', - 'mail2ellen.com', - 'mail2elliot.com', - 'mail2elsalvador.com', - 'mail2elvis.com', - 'mail2emergency.com', - 'mail2emily.com', - 'mail2engineer.com', - 'mail2english.com', - 'mail2environmentalist.com', - 'mail2eos.com', - 'mail2eric.com', - 'mail2erica.com', - 'mail2erin.com', - 'mail2erinyes.com', - 'mail2eris.com', - 'mail2eritrea.com', - 'mail2ernie.com', - 'mail2eros.com', - 'mail2estonia.com', - 'mail2ethan.com', - 'mail2ethiopia.com', - 'mail2eu.com', - 'mail2europe.com', - 'mail2eurus.com', - 'mail2eva.com', - 'mail2evan.com', - 'mail2evelyn.com', - 'mail2everything.com', - 'mail2exciting.com', - 'mail2expert.com', - 'mail2fairy.com', - 'mail2faith.com', - 'mail2fanatic.com', - 'mail2fancy.com', - 'mail2fantasy.com', - 'mail2farm.com', - 'mail2farmer.com', - 'mail2fashion.com', - 'mail2fat.com', - 'mail2feeling.com', - 'mail2female.com', - 'mail2fever.com', - 'mail2fighter.com', - 'mail2fiji.com', - 'mail2filmfestival.com', - 'mail2films.com', - 'mail2finance.com', - 'mail2finland.com', - 'mail2fireman.com', - 'mail2firm.com', - 'mail2fisherman.com', - 'mail2flexible.com', - 'mail2florence.com', - 'mail2florida.com', - 'mail2floyd.com', - 'mail2fly.com', - 'mail2fond.com', - 'mail2fondness.com', - 'mail2football.com', - 'mail2footballfan.com', - 'mail2found.com', - 'mail2france.com', - 'mail2frank.com', - 'mail2frankfurt.com', - 'mail2franklin.com', - 'mail2fred.com', - 'mail2freddie.com', - 'mail2free.com', - 'mail2freedom.com', - 'mail2french.com', - 'mail2freudian.com', - 'mail2friendship.com', - 'mail2from.com', - 'mail2fun.com', - 'mail2gabon.com', - 'mail2gabriel.com', - 'mail2gail.com', - 'mail2galaxy.com', - 'mail2gambia.com', - 'mail2games.com', - 'mail2gary.com', - 'mail2gavin.com', - 'mail2gemini.com', - 'mail2gene.com', - 'mail2genes.com', - 'mail2geneva.com', - 'mail2george.com', - 'mail2georgia.com', - 'mail2gerald.com', - 'mail2german.com', - 'mail2germany.com', - 'mail2ghana.com', - 'mail2gilbert.com', - 'mail2gina.com', - 'mail2girl.com', - 'mail2glen.com', - 'mail2gloria.com', - 'mail2goddess.com', - 'mail2gold.com', - 'mail2golfclub.com', - 'mail2golfer.com', - 'mail2gordon.com', - 'mail2government.com', - 'mail2grab.com', - 'mail2grace.com', - 'mail2graham.com', - 'mail2grandma.com', - 'mail2grandpa.com', - 'mail2grant.com', - 'mail2greece.com', - 'mail2green.com', - 'mail2greg.com', - 'mail2grenada.com', - 'mail2gsm.com', - 'mail2guard.com', - 'mail2guatemala.com', - 'mail2guy.com', - 'mail2hades.com', - 'mail2haiti.com', - 'mail2hal.com', - 'mail2handhelds.com', - 'mail2hank.com', - 'mail2hannah.com', - 'mail2harold.com', - 'mail2harry.com', - 'mail2hawaii.com', - 'mail2headhunter.com', - 'mail2heal.com', - 'mail2heather.com', - 'mail2heaven.com', - 'mail2hebe.com', - 'mail2hecate.com', - 'mail2heidi.com', - 'mail2helen.com', - 'mail2hell.com', - 'mail2help.com', - 'mail2helpdesk.com', - 'mail2henry.com', - 'mail2hephaestus.com', - 'mail2hera.com', - 'mail2hercules.com', - 'mail2herman.com', - 'mail2hermes.com', - 'mail2hespera.com', - 'mail2hestia.com', - 'mail2highschool.com', - 'mail2hindu.com', - 'mail2hip.com', - 'mail2hiphop.com', - 'mail2holland.com', - 'mail2holly.com', - 'mail2hollywood.com', - 'mail2homer.com', - 'mail2honduras.com', - 'mail2honey.com', - 'mail2hongkong.com', - 'mail2hope.com', - 'mail2horse.com', - 'mail2hot.com', - 'mail2hotel.com', - 'mail2houston.com', - 'mail2howard.com', - 'mail2hugh.com', - 'mail2human.com', - 'mail2hungary.com', - 'mail2hungry.com', - 'mail2hygeia.com', - 'mail2hyperspace.com', - 'mail2hypnos.com', - 'mail2ian.com', - 'mail2ice-cream.com', - 'mail2iceland.com', - 'mail2idaho.com', - 'mail2idontknow.com', - 'mail2illinois.com', - 'mail2imam.com', - 'mail2in.com', - 'mail2india.com', - 'mail2indian.com', - 'mail2indiana.com', - 'mail2indonesia.com', - 'mail2infinity.com', - 'mail2intense.com', - 'mail2iowa.com', - 'mail2iran.com', - 'mail2iraq.com', - 'mail2ireland.com', - 'mail2irene.com', - 'mail2iris.com', - 'mail2irresistible.com', - 'mail2irving.com', - 'mail2irwin.com', - 'mail2isaac.com', - 'mail2israel.com', - 'mail2italian.com', - 'mail2italy.com', - 'mail2jackie.com', - 'mail2jacob.com', - 'mail2jail.com', - 'mail2jaime.com', - 'mail2jake.com', - 'mail2jamaica.com', - 'mail2james.com', - 'mail2jamie.com', - 'mail2jan.com', - 'mail2jane.com', - 'mail2janet.com', - 'mail2janice.com', - 'mail2japan.com', - 'mail2japanese.com', - 'mail2jasmine.com', - 'mail2jason.com', - 'mail2java.com', - 'mail2jay.com', - 'mail2jazz.com', - 'mail2jed.com', - 'mail2jeffrey.com', - 'mail2jennifer.com', - 'mail2jenny.com', - 'mail2jeremy.com', - 'mail2jerry.com', - 'mail2jessica.com', - 'mail2jessie.com', - 'mail2jesus.com', - 'mail2jew.com', - 'mail2jeweler.com', - 'mail2jim.com', - 'mail2jimmy.com', - 'mail2joan.com', - 'mail2joann.com', - 'mail2joanna.com', - 'mail2jody.com', - 'mail2joe.com', - 'mail2joel.com', - 'mail2joey.com', - 'mail2john.com', - 'mail2join.com', - 'mail2jon.com', - 'mail2jonathan.com', - 'mail2jones.com', - 'mail2jordan.com', - 'mail2joseph.com', - 'mail2josh.com', - 'mail2joy.com', - 'mail2juan.com', - 'mail2judge.com', - 'mail2judy.com', - 'mail2juggler.com', - 'mail2julian.com', - 'mail2julie.com', - 'mail2jumbo.com', - 'mail2junk.com', - 'mail2justin.com', - 'mail2justme.com', - 'mail2k.ru', - 'mail2kansas.com', - 'mail2karate.com', - 'mail2karen.com', - 'mail2karl.com', - 'mail2karma.com', - 'mail2kathleen.com', - 'mail2kathy.com', - 'mail2katie.com', - 'mail2kay.com', - 'mail2kazakhstan.com', - 'mail2keen.com', - 'mail2keith.com', - 'mail2kelly.com', - 'mail2kelsey.com', - 'mail2ken.com', - 'mail2kendall.com', - 'mail2kennedy.com', - 'mail2kenneth.com', - 'mail2kenny.com', - 'mail2kentucky.com', - 'mail2kenya.com', - 'mail2kerry.com', - 'mail2kevin.com', - 'mail2kim.com', - 'mail2kimberly.com', - 'mail2king.com', - 'mail2kirk.com', - 'mail2kiss.com', - 'mail2kosher.com', - 'mail2kristin.com', - 'mail2kurt.com', - 'mail2kuwait.com', - 'mail2kyle.com', - 'mail2kyrgyzstan.com', - 'mail2la.com', - 'mail2lacrosse.com', - 'mail2lance.com', - 'mail2lao.com', - 'mail2larry.com', - 'mail2latvia.com', - 'mail2laugh.com', - 'mail2laura.com', - 'mail2lauren.com', - 'mail2laurie.com', - 'mail2lawrence.com', - 'mail2lawyer.com', - 'mail2lebanon.com', - 'mail2lee.com', - 'mail2leo.com', - 'mail2leon.com', - 'mail2leonard.com', - 'mail2leone.com', - 'mail2leslie.com', - 'mail2letter.com', - 'mail2liberia.com', - 'mail2libertarian.com', - 'mail2libra.com', - 'mail2libya.com', - 'mail2liechtenstein.com', - 'mail2life.com', - 'mail2linda.com', - 'mail2linux.com', - 'mail2lionel.com', - 'mail2lipstick.com', - 'mail2liquid.com', - 'mail2lisa.com', - 'mail2lithuania.com', - 'mail2litigator.com', - 'mail2liz.com', - 'mail2lloyd.com', - 'mail2lois.com', - 'mail2lola.com', - 'mail2london.com', - 'mail2looking.com', - 'mail2lori.com', - 'mail2lost.com', - 'mail2lou.com', - 'mail2louis.com', - 'mail2louisiana.com', - 'mail2lovable.com', - 'mail2love.com', - 'mail2lucky.com', - 'mail2lucy.com', - 'mail2lunch.com', - 'mail2lust.com', - 'mail2luxembourg.com', - 'mail2luxury.com', - 'mail2lyle.com', - 'mail2lynn.com', - 'mail2madagascar.com', - 'mail2madison.com', - 'mail2madrid.com', - 'mail2maggie.com', - 'mail2mail4.com', - 'mail2maine.com', - 'mail2malawi.com', - 'mail2malaysia.com', - 'mail2maldives.com', - 'mail2mali.com', - 'mail2malta.com', - 'mail2mambo.com', - 'mail2man.com', - 'mail2mandy.com', - 'mail2manhunter.com', - 'mail2mankind.com', - 'mail2many.com', - 'mail2marc.com', - 'mail2marcia.com', - 'mail2margaret.com', - 'mail2margie.com', - 'mail2marhaba.com', - 'mail2maria.com', - 'mail2marilyn.com', - 'mail2marines.com', - 'mail2mark.com', - 'mail2marriage.com', - 'mail2married.com', - 'mail2marries.com', - 'mail2mars.com', - 'mail2marsha.com', - 'mail2marshallislands.com', - 'mail2martha.com', - 'mail2martin.com', - 'mail2marty.com', - 'mail2marvin.com', - 'mail2mary.com', - 'mail2maryland.com', - 'mail2mason.com', - 'mail2massachusetts.com', - 'mail2matt.com', - 'mail2matthew.com', - 'mail2maurice.com', - 'mail2mauritania.com', - 'mail2mauritius.com', - 'mail2max.com', - 'mail2maxwell.com', - 'mail2maybe.com', - 'mail2mba.com', - 'mail2me4u.com', - 'mail2mechanic.com', - 'mail2medieval.com', - 'mail2megan.com', - 'mail2mel.com', - 'mail2melanie.com', - 'mail2melissa.com', - 'mail2melody.com', - 'mail2member.com', - 'mail2memphis.com', - 'mail2methodist.com', - 'mail2mexican.com', - 'mail2mexico.com', - 'mail2mgz.com', - 'mail2miami.com', - 'mail2michael.com', - 'mail2michelle.com', - 'mail2michigan.com', - 'mail2mike.com', - 'mail2milan.com', - 'mail2milano.com', - 'mail2mildred.com', - 'mail2milkyway.com', - 'mail2millennium.com', - 'mail2millionaire.com', - 'mail2milton.com', - 'mail2mime.com', - 'mail2mindreader.com', - 'mail2mini.com', - 'mail2minister.com', - 'mail2minneapolis.com', - 'mail2minnesota.com', - 'mail2miracle.com', - 'mail2missionary.com', - 'mail2mississippi.com', - 'mail2missouri.com', - 'mail2mitch.com', - 'mail2model.com', - 'mail2moldova.commail2molly.com', - 'mail2mom.com', - 'mail2monaco.com', - 'mail2money.com', - 'mail2mongolia.com', - 'mail2monica.com', - 'mail2montana.com', - 'mail2monty.com', - 'mail2moon.com', - 'mail2morocco.com', - 'mail2morpheus.com', - 'mail2mors.com', - 'mail2moscow.com', - 'mail2moslem.com', - 'mail2mouseketeer.com', - 'mail2movies.com', - 'mail2mozambique.com', - 'mail2mp3.com', - 'mail2mrright.com', - 'mail2msright.com', - 'mail2museum.com', - 'mail2music.com', - 'mail2musician.com', - 'mail2muslim.com', - 'mail2my.com', - 'mail2myboat.com', - 'mail2mycar.com', - 'mail2mycell.com', - 'mail2mygsm.com', - 'mail2mylaptop.com', - 'mail2mymac.com', - 'mail2mypager.com', - 'mail2mypalm.com', - 'mail2mypc.com', - 'mail2myphone.com', - 'mail2myplane.com', - 'mail2namibia.com', - 'mail2nancy.com', - 'mail2nasdaq.com', - 'mail2nathan.com', - 'mail2nauru.com', - 'mail2navy.com', - 'mail2neal.com', - 'mail2nebraska.com', - 'mail2ned.com', - 'mail2neil.com', - 'mail2nelson.com', - 'mail2nemesis.com', - 'mail2nepal.com', - 'mail2netherlands.com', - 'mail2network.com', - 'mail2nevada.com', - 'mail2newhampshire.com', - 'mail2newjersey.com', - 'mail2newmexico.com', - 'mail2newyork.com', - 'mail2newzealand.com', - 'mail2nicaragua.com', - 'mail2nick.com', - 'mail2nicole.com', - 'mail2niger.com', - 'mail2nigeria.com', - 'mail2nike.com', - 'mail2no.com', - 'mail2noah.com', - 'mail2noel.com', - 'mail2noelle.com', - 'mail2normal.com', - 'mail2norman.com', - 'mail2northamerica.com', - 'mail2northcarolina.com', - 'mail2northdakota.com', - 'mail2northpole.com', - 'mail2norway.com', - 'mail2notus.com', - 'mail2noway.com', - 'mail2nowhere.com', - 'mail2nuclear.com', - 'mail2nun.com', - 'mail2ny.com', - 'mail2oasis.com', - 'mail2oceanographer.com', - 'mail2ohio.com', - 'mail2ok.com', - 'mail2oklahoma.com', - 'mail2oliver.com', - 'mail2oman.com', - 'mail2one.com', - 'mail2onfire.com', - 'mail2online.com', - 'mail2oops.com', - 'mail2open.com', - 'mail2ophthalmologist.com', - 'mail2optometrist.com', - 'mail2oregon.com', - 'mail2oscars.com', - 'mail2oslo.com', - 'mail2painter.com', - 'mail2pakistan.com', - 'mail2palau.com', - 'mail2pan.com', - 'mail2panama.com', - 'mail2paraguay.com', - 'mail2paralegal.com', - 'mail2paris.com', - 'mail2park.com', - 'mail2parker.com', - 'mail2party.com', - 'mail2passion.com', - 'mail2pat.com', - 'mail2patricia.com', - 'mail2patrick.com', - 'mail2patty.com', - 'mail2paul.com', - 'mail2paula.com', - 'mail2pay.com', - 'mail2peace.com', - 'mail2pediatrician.com', - 'mail2peggy.com', - 'mail2pennsylvania.com', - 'mail2perry.com', - 'mail2persephone.com', - 'mail2persian.com', - 'mail2peru.com', - 'mail2pete.com', - 'mail2peter.com', - 'mail2pharmacist.com', - 'mail2phil.com', - 'mail2philippines.com', - 'mail2phoenix.com', - 'mail2phonecall.com', - 'mail2phyllis.com', - 'mail2pickup.com', - 'mail2pilot.com', - 'mail2pisces.com', - 'mail2planet.com', - 'mail2platinum.com', - 'mail2plato.com', - 'mail2pluto.com', - 'mail2pm.com', - 'mail2podiatrist.com', - 'mail2poet.com', - 'mail2poland.com', - 'mail2policeman.com', - 'mail2policewoman.com', - 'mail2politician.com', - 'mail2pop.com', - 'mail2pope.com', - 'mail2popular.com', - 'mail2portugal.com', - 'mail2poseidon.com', - 'mail2potatohead.com', - 'mail2power.com', - 'mail2presbyterian.com', - 'mail2president.com', - 'mail2priest.com', - 'mail2prince.com', - 'mail2princess.com', - 'mail2producer.com', - 'mail2professor.com', - 'mail2protect.com', - 'mail2psychiatrist.com', - 'mail2psycho.com', - 'mail2psychologist.com', - 'mail2qatar.com', - 'mail2queen.com', - 'mail2rabbi.com', - 'mail2race.com', - 'mail2racer.com', - 'mail2rachel.com', - 'mail2rage.com', - 'mail2rainmaker.com', - 'mail2ralph.com', - 'mail2randy.com', - 'mail2rap.com', - 'mail2rare.com', - 'mail2rave.com', - 'mail2ray.com', - 'mail2raymond.com', - 'mail2realtor.com', - 'mail2rebecca.com', - 'mail2recruiter.com', - 'mail2recycle.com', - 'mail2redhead.com', - 'mail2reed.com', - 'mail2reggie.com', - 'mail2register.com', - 'mail2rent.com', - 'mail2republican.com', - 'mail2resort.com', - 'mail2rex.com', - 'mail2rhodeisland.com', - 'mail2rich.com', - 'mail2richard.com', - 'mail2ricky.com', - 'mail2ride.com', - 'mail2riley.com', - 'mail2rita.com', - 'mail2rob.com', - 'mail2robert.com', - 'mail2roberta.com', - 'mail2robin.com', - 'mail2rock.com', - 'mail2rocker.com', - 'mail2rod.com', - 'mail2rodney.com', - 'mail2romania.com', - 'mail2rome.com', - 'mail2ron.com', - 'mail2ronald.com', - 'mail2ronnie.com', - 'mail2rose.com', - 'mail2rosie.com', - 'mail2roy.com', - 'mail2rss.org', - 'mail2rudy.com', - 'mail2rugby.com', - 'mail2runner.com', - 'mail2russell.com', - 'mail2russia.com', - 'mail2russian.com', - 'mail2rusty.com', - 'mail2ruth.com', - 'mail2rwanda.com', - 'mail2ryan.com', - 'mail2sa.com', - 'mail2sabrina.com', - 'mail2safe.com', - 'mail2sagittarius.com', - 'mail2sail.com', - 'mail2sailor.com', - 'mail2sal.com', - 'mail2salaam.com', - 'mail2sam.com', - 'mail2samantha.com', - 'mail2samoa.com', - 'mail2samurai.com', - 'mail2sandra.com', - 'mail2sandy.com', - 'mail2sanfrancisco.com', - 'mail2sanmarino.com', - 'mail2santa.com', - 'mail2sara.com', - 'mail2sarah.com', - 'mail2sat.com', - 'mail2saturn.com', - 'mail2saudi.com', - 'mail2saudiarabia.com', - 'mail2save.com', - 'mail2savings.com', - 'mail2school.com', - 'mail2scientist.com', - 'mail2scorpio.com', - 'mail2scott.com', - 'mail2sean.com', - 'mail2search.com', - 'mail2seattle.com', - 'mail2secretagent.com', - 'mail2senate.com', - 'mail2senegal.com', - 'mail2sensual.com', - 'mail2seth.com', - 'mail2sevenseas.com', - 'mail2sexy.com', - 'mail2seychelles.com', - 'mail2shane.com', - 'mail2sharon.com', - 'mail2shawn.com', - 'mail2ship.com', - 'mail2shirley.com', - 'mail2shoot.com', - 'mail2shuttle.com', - 'mail2sierraleone.com', - 'mail2simon.com', - 'mail2singapore.com', - 'mail2single.com', - 'mail2site.com', - 'mail2skater.com', - 'mail2skier.com', - 'mail2sky.com', - 'mail2sleek.com', - 'mail2slim.com', - 'mail2slovakia.com', - 'mail2slovenia.com', - 'mail2smile.com', - 'mail2smith.com', - 'mail2smooth.com', - 'mail2soccer.com', - 'mail2soccerfan.com', - 'mail2socialist.com', - 'mail2soldier.com', - 'mail2somalia.com', - 'mail2son.com', - 'mail2song.com', - 'mail2sos.com', - 'mail2sound.com', - 'mail2southafrica.com', - 'mail2southamerica.com', - 'mail2southcarolina.com', - 'mail2southdakota.com', - 'mail2southkorea.com', - 'mail2southpole.com', - 'mail2spain.com', - 'mail2spanish.com', - 'mail2spare.com', - 'mail2spectrum.com', - 'mail2splash.com', - 'mail2sponsor.com', - 'mail2sports.com', - 'mail2srilanka.com', - 'mail2stacy.com', - 'mail2stan.com', - 'mail2stanley.com', - 'mail2star.com', - 'mail2state.com', - 'mail2stephanie.com', - 'mail2steve.com', - 'mail2steven.com', - 'mail2stewart.com', - 'mail2stlouis.com', - 'mail2stock.com', - 'mail2stockholm.com', - 'mail2stockmarket.com', - 'mail2storage.com', - 'mail2store.com', - 'mail2strong.com', - 'mail2student.com', - 'mail2studio.com', - 'mail2studio54.com', - 'mail2stuntman.com', - 'mail2subscribe.com', - 'mail2sudan.com', - 'mail2superstar.com', - 'mail2surfer.com', - 'mail2suriname.com', - 'mail2susan.com', - 'mail2suzie.com', - 'mail2swaziland.com', - 'mail2sweden.com', - 'mail2sweetheart.com', - 'mail2swim.com', - 'mail2swimmer.com', - 'mail2swiss.com', - 'mail2switzerland.com', - 'mail2sydney.com', - 'mail2sylvia.com', - 'mail2syria.com', - 'mail2taboo.com', - 'mail2taiwan.com', - 'mail2tajikistan.com', - 'mail2tammy.com', - 'mail2tango.com', - 'mail2tanya.com', - 'mail2tanzania.com', - 'mail2tara.com', - 'mail2taurus.com', - 'mail2taxi.com', - 'mail2taxidermist.com', - 'mail2taylor.com', - 'mail2taz.com', - 'mail2teacher.com', - 'mail2technician.com', - 'mail2ted.com', - 'mail2telephone.com', - 'mail2teletubbie.com', - 'mail2tenderness.com', - 'mail2tennessee.com', - 'mail2tennis.com', - 'mail2tennisfan.com', - 'mail2terri.com', - 'mail2terry.com', - 'mail2test.com', - 'mail2texas.com', - 'mail2thailand.com', - 'mail2therapy.com', - 'mail2think.com', - 'mail2tickets.com', - 'mail2tiffany.com', - 'mail2tim.com', - 'mail2time.com', - 'mail2timothy.com', - 'mail2tina.com', - 'mail2titanic.com', - 'mail2toby.com', - 'mail2todd.com', - 'mail2togo.com', - 'mail2tom.com', - 'mail2tommy.com', - 'mail2tonga.com', - 'mail2tony.com', - 'mail2touch.com', - 'mail2tourist.com', - 'mail2tracey.com', - 'mail2tracy.com', - 'mail2tramp.com', - 'mail2travel.com', - 'mail2traveler.com', - 'mail2travis.com', - 'mail2trekkie.com', - 'mail2trex.com', - 'mail2triallawyer.com', - 'mail2trick.com', - 'mail2trillionaire.com', - 'mail2troy.com', - 'mail2truck.com', - 'mail2trump.com', - 'mail2try.com', - 'mail2tunisia.com', - 'mail2turbo.com', - 'mail2turkey.com', - 'mail2turkmenistan.com', - 'mail2tv.com', - 'mail2tycoon.com', - 'mail2tyler.com', - 'mail2u4me.com', - 'mail2uae.com', - 'mail2uganda.com', - 'mail2uk.com', - 'mail2ukraine.com', - 'mail2uncle.com', - 'mail2unsubscribe.com', - 'mail2uptown.com', - 'mail2uruguay.com', - 'mail2usa.com', - 'mail2utah.com', - 'mail2uzbekistan.com', - 'mail2v.com', - 'mail2vacation.com', - 'mail2valentines.com', - 'mail2valerie.com', - 'mail2valley.com', - 'mail2vamoose.com', - 'mail2vanessa.com', - 'mail2vanuatu.com', - 'mail2venezuela.com', - 'mail2venous.com', - 'mail2venus.com', - 'mail2vermont.com', - 'mail2vickie.com', - 'mail2victor.com', - 'mail2victoria.com', - 'mail2vienna.com', - 'mail2vietnam.com', - 'mail2vince.com', - 'mail2virginia.com', - 'mail2virgo.com', - 'mail2visionary.com', - 'mail2vodka.com', - 'mail2volleyball.com', - 'mail2waiter.com', - 'mail2wallstreet.com', - 'mail2wally.com', - 'mail2walter.com', - 'mail2warren.com', - 'mail2washington.com', - 'mail2wave.com', - 'mail2way.com', - 'mail2waycool.com', - 'mail2wayne.com', - 'mail2webmaster.com', - 'mail2webtop.com', - 'mail2webtv.com', - 'mail2weird.com', - 'mail2wendell.com', - 'mail2wendy.com', - 'mail2westend.com', - 'mail2westvirginia.com', - 'mail2whether.com', - 'mail2whip.com', - 'mail2white.com', - 'mail2whitehouse.com', - 'mail2whitney.com', - 'mail2why.com', - 'mail2wilbur.com', - 'mail2wild.com', - 'mail2willard.com', - 'mail2willie.com', - 'mail2wine.com', - 'mail2winner.com', - 'mail2wired.com', - 'mail2wisconsin.com', - 'mail2woman.com', - 'mail2wonder.com', - 'mail2world.com', - 'mail2worship.com', - 'mail2wow.com', - 'mail2www.com', - 'mail2wyoming.com', - 'mail2xfiles.com', - 'mail2xox.com', - 'mail2yachtclub.com', - 'mail2yahalla.com', - 'mail2yemen.com', - 'mail2yes.com', - 'mail2yugoslavia.com', - 'mail2zack.com', - 'mail2zambia.com', - 'mail2zenith.com', - 'mail2zephir.com', - 'mail2zeus.com', - 'mail2zipper.com', - 'mail2zoo.com', - 'mail2zoologist.com', - 'mail2zurich.com', - 'mail3000.com', - 'mail333.com', - 'mail4trash.com', - 'mail4u.info', - 'mailandftp.com', - 'mailandnews.com', - 'mailas.com', - 'mailasia.com', - 'mailbolt.com', - 'mailbomb.net', - 'mailboom.com', - 'mailbox.as', - 'mailbox.co.za', - 'mailbox.gr', - 'mailbox.hu', - 'mailbox72.biz', - 'mailbox80.biz', - 'mailbr.com.br', - 'mailc.net', - 'mailcan.com', - 'mailcat.biz', - 'mailcc.com', - 'mailchoose.co', - 'mailcity.com', - 'mailclub.fr', - 'mailclub.net', - 'maildrop.cc', - 'maildrop.gq', - 'maildx.com', - 'mailed.ro', - 'mailexcite.com', - 'mailfa.tk', - 'mailfence.com', - 'mailforce.net', - 'mailforspam.com', - 'mailfree.gq', - 'mailfs.com', - 'mailftp.com', - 'mailgenie.net', - 'mailguard.me', - 'mailhaven.com', - 'mailhood.com', - 'mailimate.com', - 'mailinator.com', - 'mailinator.org', - 'mailinator.us', - 'mailinblack.com', - 'mailingaddress.org', - 'mailingweb.com', - 'mailisent.com', - 'mailismagic.com', - 'mailite.com', - 'mailmate.com', - 'mailme.dk', - 'mailme.gq', - 'mailme24.com', - 'mailmight.com', - 'mailmij.nl', - 'mailnator.com', - 'mailnew.com', - 'mailops.com', - 'mailoye.com', - 'mailpanda.com', - 'mailpick.biz', - 'mailpokemon.com', - 'mailpost.zzn.com', - 'mailpride.com', - 'mailproxsy.com', - 'mailpuppy.com', - 'mailquack.com', - 'mailrock.biz', - 'mailroom.com', - 'mailru.com', - 'mailsac.com', - 'mailseal.de', - 'mailsent.net', - 'mailservice.ms', - 'mailshuttle.com', - 'mailslapping.com', - 'mailstart.com', - 'mailstartplus.com', - 'mailsurf.com', - 'mailtag.com', - 'mailtemp.info', - 'mailto.de', - 'mailtothis.com', - 'mailueberfall.de', - 'mailup.net', - 'mailwire.com', - 'mailworks.org', - 'mailzi.ru', - 'mailzilla.org', - 'maktoob.com', - 'malayalamtelevision.net', - 'maltesemail.com', - 'mamber.net', - 'manager.de', - 'mancity.net', - 'mantrafreenet.com', - 'mantramail.com', - 'mantraonline.com', - 'manybrain.com', - 'marchmail.com', - 'mariahc.com', - 'marijuana.com', - 'marijuana.nl', - 'married-not.com', - 'marsattack.com', - 'martindalemail.com', - 'mash4077.com', - 'masrawy.com', - 'matmail.com', - 'mauimail.com', - 'mauritius.com', - 'maxleft.com', - 'maxmail.co.uk', - 'mbox.com.au', - 'mchsi.com', - 'me-mail.hu', - 'me.com', - 'medical.net.au', - 'medscape.com', - 'meetingmall.com', - 'megago.com', - 'megamail.pt', - 'megapoint.com', - 'mehrani.com', - 'mehtaweb.com', - 'meine-dateien.info', - 'meine-diashow.de', - 'meine-fotos.info', - 'meine-urlaubsfotos.de', - 'mekhong.com', - 'melodymail.com', - 'meloo.com', - 'merda.flu.cc', - 'merda.igg.biz', - 'merda.nut.cc', - 'merda.usa.cc', - 'message.hu', - 'message.myspace.com', - 'messages.to', - 'metacrawler.com', - 'metalfan.com', - 'metaping.com', - 'metta.lk', - 'mexicomail.com', - 'mezimages.net', - 'mfsa.ru', - 'mierdamail.com', - 'miesto.sk', - 'mighty.co.za', - 'migmail.net', - 'migmail.pl', - 'migumail.com', - 'miho-nakayama.com', - 'mikrotamanet.com', - 'millionaireintraining.com', - 'millionairemail.com', - 'milmail.com', - 'mindless.com', - 'mindspring.com', - 'minister.com', - 'misery.net', - 'mittalweb.com', - 'mixmail.com', - 'mjfrogmail.com', - 'ml1.net', - 'mlb.bounce.ed10.net', - 'mm.st', - 'mns.ru', - 'moakt.com', - 'mobilbatam.com', - 'mobileninja.co.uk', - 'mochamail.com', - 'mohammed.com', - 'mohmal.com', - 'moldova.cc', - 'moldova.com', - 'moldovacc.com', - 'momslife.com', - 'monemail.com', - 'money.net', - 'montevideo.com.uy', - 'monumentmail.com', - 'moonman.com', - 'moose-mail.com', - 'mor19.uu.gl', - 'mortaza.com', - 'mosaicfx.com', - 'moscowmail.com', - 'most-wanted.com', - 'mostlysunny.com', - 'motormania.com', - 'movemail.com', - 'movieluver.com', - 'mox.pp.ua', - 'mp4.it', - 'mr-potatohead.com', - 'mscold.com', - 'msgbox.com', - 'msn.cn', - 'msn.com', - 'msn.nl', - 'mt2015.com', - 'mt2016.com', - 'mttestdriver.com', - 'muehlacker.tk', - 'muell.icu', - 'muellmail.com', - 'muellemail.com', - 'mundomail.net', - 'munich.com', - 'music.com', - 'musician.org', - 'musicscene.org', - 'muskelshirt.de', - 'muslim.com', - 'muslimsonline.com', - 'mutantweb.com', - 'mvrht.com', - 'my.com', - 'my10minutemail.com', - 'mybox.it', - 'mycabin.com', - 'mycity.com', - 'mycool.com', - 'mydomain.com', - 'mydotcomaddress.com', - 'myfamily.com', - 'myfastmail.com', - 'mygo.com', - 'myiris.com', - 'mymacmail.com', - 'mynamedot.com', - 'mynet.com', - 'mynetaddress.com', - 'mynetstore.de', - 'myownemail.com', - 'myownfriends.com', - 'mypacks.net', - 'mypad.com', - 'mypersonalemail.com', - 'myplace.com', - 'myrambler.ru', - 'myrealbox.com', - 'myremarq.com', - 'myself.com', - 'myspaceinc.net', - 'myspamless.com', - 'mystupidjob.com', - 'mytemp.email', - 'mythirdage.com', - 'myway.com', - 'myworldmail.com', - 'n2.com', - 'n2baseball.com', - 'n2business.com', - 'n2mail.com', - 'n2soccer.com', - 'n2software.com', - 'nabc.biz', - 'nafe.com', - 'nagpal.net', - 'nakedgreens.com', - 'name.com', - 'nameplanet.com', - 'nandomail.com', - 'naplesnews.net', - 'naseej.com', - 'nativestar.net', - 'nativeweb.net', - 'naui.net', - 'naver.com', - 'navigator.lv', - 'navy.org', - 'naz.com', - 'nc.rr.com', - 'nchoicemail.com', - 'neeva.net', - 'nemra1.com', - 'nenter.com', - 'neo.rr.com', - 'nervhq.org', - 'net-c.be', - 'net-c.ca', - 'net-c.cat', - 'net-c.com', - 'net-c.es', - 'net-c.fr', - 'net-c.it', - 'net-c.lu', - 'net-c.nl', - 'net-c.pl', - 'net-pager.net', - 'net-shopping.com', - 'net4b.pt', - 'net4you.at', - 'netbounce.com', - 'netbroadcaster.com', - 'netby.dk', - 'netc.eu', - 'netc.fr', - 'netc.it', - 'netc.lu', - 'netc.pl', - 'netcenter-vn.net', - 'netcmail.com', - 'netcourrier.com', - 'netexecutive.com', - 'netexpressway.com', - 'netgenie.com', - 'netian.com', - 'netizen.com.ar', - 'netlane.com', - 'netlimit.com', - 'netmongol.com', - 'netnet.com.sg', - 'netnoir.net', - 'netpiper.com', - 'netposta.net', - 'netralink.com', - 'netscape.net', - 'netscapeonline.co.uk', - 'netspace.net.au', - 'netspeedway.com', - 'netsquare.com', - 'netster.com', - 'nettaxi.com', - 'nettemail.com', - 'netterchef.de', - 'netti.fi', - 'netzero.com', - 'netzero.net', - 'netzidiot.de', - 'neue-dateien.de', - 'neuro.md', - 'newmail.com', - 'newmail.net', - 'newmail.ru', - 'newsboysmail.com', - 'newyork.com', - 'nextmail.ru', - 'nexxmail.com', - 'nfmail.com', - 'nicebush.com', - 'nicegal.com', - 'nicholastse.net', - 'nicolastse.com', - 'nightmail.com', - 'nikopage.com', - 'nimail.com', - 'ninfan.com', - 'nirvanafan.com', - 'nmail.cf', - 'noavar.com', - 'nonpartisan.com', - 'nonspam.eu', - 'nonspammer.de', - 'norika-fujiwara.com', - 'norikomail.com', - 'northgates.net', - 'nospammail.net', - 'nospamthanks.info', - 'nowhere.org', - 'ntelos.net', - 'ntlhelp.net', - 'ntlworld.com', - 'ntscan.com', - 'null.net', - 'nullbox.info', - 'nur-fuer-spam.de', - 'nus.edu.sg', - 'nwldx.com', - 'nwytg.net', - 'nxt.ru', - 'ny.com', - 'nybella.com', - 'nyc.com', - 'nycmail.com', - 'nzoomail.com', - 'o-tay.com', - 'o2.co.uk', - 'oaklandas-fan.com', - 'oath.com', - 'oceanfree.net', - 'odaymail.com', - 'oddpost.com', - 'odmail.com', - 'office-dateien.de', - 'office-email.com', - 'offroadwarrior.com', - 'oicexchange.com', - 'oida.icu', - 'oikrach.com', - 'okbank.com', - 'okhuman.com', - 'okmad.com', - 'okmagic.com', - 'okname.net', - 'okuk.com', - 'oldies104mail.com', - 'ole.com', - 'olemail.com', - 'olympist.net', - 'olypmall.ru', - 'omaninfo.com', - 'omen.ru', - 'onebox.com', - 'onenet.com.ar', - 'oneoffmail.com', - 'onet.com.pl', - 'onet.eu', - 'onet.pl', - 'oninet.pt', - 'online.ie', - 'online.ms', - 'online.nl', - 'onlinewiz.com', - 'onmilwaukee.com', - 'onobox.com', - 'op.pl', - 'opayq.com', - 'openmailbox.org', - 'operafan.com', - 'operamail.com', - 'opoczta.pl', - 'optician.com', - 'optonline.net', - 'optusnet.com.au', - 'orange.fr', - 'orbitel.bg', - 'orgmail.net', - 'orthodontist.net', - 'osite.com.br', - 'oso.com', - 'otakumail.com', - 'our-computer.com', - 'our-office.com', - 'our.st', - 'ourbrisbane.com', - 'ourklips.com', - 'ournet.md', - 'outgun.com', - 'outlawspam.com', - 'outlook.at', - 'outlook.be', - 'outlook.cl', - 'outlook.co.id', - 'outlook.co.il', - 'outlook.co.nz', - 'outlook.co.th', - 'outlook.com', - 'outlook.com.au', - 'outlook.com.br', - 'outlook.com.gr', - 'outlook.com.pe', - 'outlook.com.tr', - 'outlook.com.vn', - 'outlook.cz', - 'outlook.de', - 'outlook.dk', - 'outlook.es', - 'outlook.fr', - 'outlook.hu', - 'outlook.ie', - 'outlook.in', - 'outlook.it', - 'outlook.jp', - 'outlook.kr', - 'outlook.lv', - 'outlook.my', - 'outlook.nl', - 'outlook.ph', - 'outlook.pt', - 'outlook.sa', - 'outlook.sg', - 'outlook.sk', - 'over-the-rainbow.com', - 'ownmail.net', - 'ozbytes.net.au', - 'ozemail.com.au', - 'pacbell.net', - 'pacific-ocean.com', - 'pacific-re.com', - 'pacificwest.com', - 'packersfan.com', - 'pagina.de', - 'pagons.org', - 'pakistanmail.com', - 'pakistanoye.com', - 'palestinemail.com', - 'pandora.be', - 'papierkorb.me', - 'parkjiyoon.com', - 'parsmail.com', - 'partlycloudy.com', - 'partybombe.de', - 'partyheld.de', - 'partynight.at', - 'parvazi.com', - 'passwordmail.com', - 'pathfindermail.com', - 'pconnections.net', - 'pcpostal.com', - 'pcsrock.com', - 'pcusers.otherinbox.com', - 'pediatrician.com', - 'penpen.com', - 'peoplepc.com', - 'peopleweb.com', - 'pepbot.com', - 'perfectmail.com', - 'perso.be', - 'personal.ro', - 'personales.com', - 'petlover.com', - 'petml.com', - 'pettypool.com', - 'pezeshkpour.com', - 'pfui.ru', - 'phayze.com', - 'phone.net', - 'photo-impact.eu', - 'photographer.net', - 'phpbb.uu.gl', - 'phreaker.net', - 'phus8kajuspa.cu.cc', - 'physicist.net', - 'pianomail.com', - 'pickupman.com', - 'picusnet.com', - 'pigpig.net', - 'pinoymail.com', - 'piracha.net', - 'pisem.net', - 'pjjkp.com', - 'planet.nl', - 'planetaccess.com', - 'planetarymotion.net', - 'planetearthinter.net', - 'planetmail.com', - 'planetmail.net', - 'planetout.com', - 'plasa.com', - 'playersodds.com', - 'playful.com', - 'playstation.sony.com', - 'plus.com', - 'plus.google.com', - 'plusmail.com.br', - 'pmail.net', - 'pobox.hu', - 'pobox.sk', - 'pochta.ru', - 'poczta.fm', - 'poczta.onet.pl', - 'poetic.com', - 'pokemail.net', - 'pokemonpost.com', - 'pokepost.com', - 'polandmail.com', - 'polbox.com', - 'policeoffice.com', - 'politician.com', - 'polizisten-duzer.de', - 'polyfaust.com', - 'pool-sharks.com', - 'poond.com', - 'popaccount.com', - 'popmail.com', - 'popsmail.com', - 'popstar.com', - 'portugalmail.com', - 'portugalmail.pt', - 'portugalnet.com', - 'positive-thinking.com', - 'post.com', - 'post.cz', - 'post.sk', - 'posta.ro', - 'postaccesslite.com', - 'postafree.com', - 'postaweb.com', - 'posteo.at', - 'posteo.be', - 'posteo.ch', - 'posteo.cl', - 'posteo.co', - 'posteo.de', - 'posteo.dk', - 'posteo.es', - 'posteo.gl', - 'posteo.net', - 'posteo.no', - 'posteo.us', - 'postfach.cc', - 'postinbox.com', - 'postino.ch', - 'postmark.net', - 'postmaster.co.uk', - 'postmaster.twitter.com', - 'postpro.net', - 'pousa.com', - 'powerfan.com', - 'pp.inet.fi', - 'praize.com', - 'premium-mail.fr', - 'premiumservice.com', - 'presidency.com', - 'press.co.jp', - 'priest.com', - 'primposta.com', - 'primposta.hu', - 'privy-mail.com', - 'privymail.de', - 'pro.hu', - 'probemail.com', - 'prodigy.net', - 'progetplus.it', - 'programist.ru', - 'programmer.net', - 'programozo.hu', - 'proinbox.com', - 'project2k.com', - 'promessage.com', - 'prontomail.com', - 'protestant.com', - 'protonmail.com', - 'prydirect.info', - 'psv-supporter.com', - 'ptd.net', - 'public-files.de', - 'public.usa.com', - 'publicist.com', - 'pulp-fiction.com', - 'punkass.com', - 'purpleturtle.com', - 'put2.net', - 'pwrby.com', - 'q.com', - 'qatarmail.com', - 'qmail.com', - 'qprfans.com', - 'qq.com', - 'qrio.com', - 'quackquack.com', - 'quakemail.com', - 'qualityservice.com', - 'quantentunnel.de', - 'qudsmail.com', - 'quepasa.com', - 'quickhosts.com', - 'quickmail.nl', - 'quicknet.nl', - 'quickwebmail.com', - 'quiklinks.com', - 'quikmail.com', - 'qv7.info', - 'qwest.net', - 'qwestoffice.net', - 'r-o-o-t.com', - 'raakim.com', - 'racedriver.com', - 'racefanz.com', - 'racingfan.com.au', - 'racingmail.com', - 'radicalz.com', - 'radiku.ye.vc', - 'radiologist.net', - 'ragingbull.com', - 'ralib.com', - 'rambler.ru', - 'ranmamail.com', - 'rastogi.net', - 'ratt-n-roll.com', - 'rattle-snake.com', - 'raubtierbaendiger.de', - 'ravearena.com', - 'ravemail.com', - 'razormail.com', - 'rccgmail.org', - 'rcn.com', - 'realemail.net', - 'reality-concept.club', - 'reallyfast.biz', - 'reallyfast.info', - 'reallymymail.com', - 'realradiomail.com', - 'realtyagent.com', - 'reborn.com', - 'reconmail.com', - 'recycler.com', - 'recyclermail.com', - 'rediff.com', - 'rediffmail.com', - 'rediffmailpro.com', - 'rednecks.com', - 'redseven.de', - 'redsfans.com', - 'regbypass.com', - 'reggaefan.com', - 'registerednurses.com', - 'regspaces.tk', - 'reincarnate.com', - 'religious.com', - 'remail.ga', - 'renren.com', - 'repairman.com', - 'reply.hu', - 'reply.ticketmaster.com', - 'representative.com', - 'rescueteam.com', - 'resgedvgfed.tk', - 'resource.calendar.google.com', - 'resumemail.com', - 'rezai.com', - 'rhyta.com', - 'richmondhill.com', - 'rickymail.com', - 'rin.ru', - 'riopreto.com.br', - 'rklips.com', - 'rn.com', - 'ro.ru', - 'roadrunner.com', - 'roanokemail.com', - 'rock.com', - 'rocketmail.com', - 'rocketship.com', - 'rockfan.com', - 'rodrun.com', - 'rogers.com', - 'rome.com', - 'roosh.com', - 'rootprompt.org', - 'roughnet.com', - 'royal.net', - 'rr.com', - 'rrohio.com', - 'rsub.com', - 'rubyridge.com', - 'runbox.com', - 'rushpost.com', - 'ruttolibero.com', - 'rvshop.com', - 's-mail.com', - 'sabreshockey.com', - 'sacbeemail.com', - 'saeuferleber.de', - 'safe-mail.net', - 'safrica.com', - 'sagra.lu', - 'sags-per-mail.de', - 'sailormoon.com', - 'saintly.com', - 'saintmail.net', - 'sale-sale-sale.com', - 'salehi.net', - 'salesperson.net', - 'samerica.com', - 'samilan.net', - 'sammimail.com', - 'sandelf.de', - 'sanfranmail.com', - 'sanook.com', - 'sapo.pt', - 'saudia.com', - 'savelife.ml', - 'sayhi.net', - 'saynotospams.com', - 'sbcglbal.net', - 'sbcglobal.com', - 'sbcglobal.net', - 'scandalmail.com', - 'scarlet.nl', - 'schafmail.de', - 'schizo.com', - 'schmusemail.de', - 'schoolemail.com', - 'schoolmail.com', - 'schoolsucks.com', - 'schreib-doch-mal-wieder.de', - 'schweiz.org', - 'sci.fi', - 'scientist.com', - 'scifianime.com', - 'scotland.com', - 'scotlandmail.com', - 'scottishmail.co.uk', - 'scottsboro.org', - 'scubadiving.com', - 'seanet.com', - 'search.ua', - 'searchwales.com', - 'sebil.com', - 'seckinmail.com', - 'secret-police.com', - 'secretary.net', - 'secretservices.net', - 'secure-mail.biz', - 'secure-mail.cc', - 'seductive.com', - 'seekstoyboy.com', - 'seguros.com.br', - 'selfdestructingmail.com', - 'send.hu', - 'sendme.cz', - 'sendspamhere.com', - 'sent.as', - 'sent.at', - 'sent.com', - 'sentrismail.com', - 'serga.com.ar', - 'servemymail.com', - 'servermaps.net', - 'sesmail.com', - 'sexmagnet.com', - 'seznam.cz', - 'shahweb.net', - 'shaniastuff.com', - 'shared-files.de', - 'sharedmailbox.org', - 'sharmaweb.com', - 'shaw.ca', - 'she.com', - 'shieldedmail.com', - 'shinedyoureyes.com', - 'shitaway.cf', - 'shitaway.cu.cc', - 'shitaway.ga', - 'shitaway.gq', - 'shitaway.ml', - 'shitaway.tk', - 'shitaway.usa.cc', - 'shitmail.de', - 'shitmail.org', - 'shitware.nl', - 'shockinmytown.cu.cc', - 'shootmail.com', - 'shortmail.com', - 'shotgun.hu', - 'showslow.de', - 'shuf.com', - 'sialkotcity.com', - 'sialkotian.com', - 'sialkotoye.com', - 'sify.com', - 'silkroad.net', - 'sina.cn', - 'sina.com', - 'sinamail.com', - 'singapore.com', - 'singles4jesus.com', - 'singmail.com', - 'singnet.com.sg', - 'sinnlos-mail.de', - 'siteposter.net', - 'skafan.com', - 'skeefmail.com', - 'skim.com', - 'skizo.hu', - 'skrx.tk', - 'sky.com', - 'skynet.be', - 'slamdunkfan.com', - 'slave-auctions.net', - 'slingshot.com', - 'slippery.email', - 'slipry.net', - 'slo.net', - 'slotter.com', - 'smap.4nmv.ru', - 'smapxsmap.net', - 'smashmail.de', - 'smellrear.com', - 'smileyface.comsmithemail.net', - 'smoothmail.com', - 'sms.at', - 'snail-mail.net', - 'snakebite.com', - 'snakemail.com', - 'sndt.net', - 'sneakemail.com', - 'snet.net', - 'sniper.hu', - 'snkmail.com', - 'snoopymail.com', - 'snowboarding.com', - 'snowdonia.net', - 'socamail.com', - 'socceramerica.net', - 'soccermail.com', - 'soccermomz.com', - 'social-mailer.tk', - 'socialworker.net', - 'sociologist.com', - 'sofort-mail.de', - 'sofortmail.de', - 'softhome.net', - 'sogou.com', - 'sohu.com', - 'sol.dk', - 'solar-impact.pro', - 'solcon.nl', - 'soldier.hu', - 'solution4u.com', - 'solvemail.info', - 'songwriter.net', - 'sonnenkinder.org', - 'soodomail.com', - 'soon.com', - 'soulfoodcookbook.com', - 'sp.nl', - 'space-bank.com', - 'space-man.com', - 'space-ship.com', - 'space-travel.com', - 'space.com', - 'spacemart.com', - 'spacetowns.com', - 'spacewar.com', - 'spainmail.com', - 'spam.2012-2016.ru', - 'spamavert.com', - 'spambob.com', - 'spambob.org', - 'spambog.net', - 'spambooger.com', - 'spam.care', - 'spamcero.com', - 'spamdecoy.net', - 'spameater.com', - 'spameater.org', - 'spamex.com', - 'spamfree24.info', - 'spamfree24.net', - 'spamgoes.in', - 'spaminator.de', - 'spamkill.info', - 'spaml.com', - 'spamoff.de', - 'spamstack.net', - 'spartapiet.com', - 'spazmail.com', - 'speedemail.net', - 'speedpost.net', - 'speedrules.com', - 'speedrulz.com', - 'speedymail.org', - 'sperke.net', - 'spils.com', - 'spinfinder.com', - 'spl.at', - 'spoko.pl', - 'spoofmail.de', - 'sportemail.com', - 'sportsmail.com', - 'sporttruckdriver.com', - 'spray.no', - 'spray.se', - 'spybox.de', - 'spymac.com', - 'sraka.xyz', - 'srilankan.net', - 'ssl-mail.com', - 'st-davids.net', - 'stade.fr', - 'stalag13.com', - 'stargateradio.com', - 'starmail.com', - 'starmail.org', - 'starmedia.com', - 'starplace.com', - 'starspath.com', - 'start.com.au', - 'startkeys.com', - 'stinkefinger.net', - 'stipte.nl', - 'stoned.com', - 'stones.com', - 'stop-my-spam.pp.ua', - 'stopdropandroll.com', - 'storksite.com', - 'streber24.de', - 'streetwisemail.com', - 'stribmail.com', - 'strompost.com', - 'strongguy.com', - 'student.su', - 'studentcenter.org', - 'stuffmail.de', - 'subram.com', - 'sudanmail.net', - 'sudolife.me', - 'sudolife.net', - 'sudomail.biz', - 'sudomail.com', - 'sudomail.net', - 'sudoverse.com', - 'sudoverse.net', - 'sudoweb.net', - 'sudoworld.com', - 'sudoworld.net', - 'suhabi.com', - 'suisse.org', - 'sukhumvit.net', - 'sunpoint.net', - 'sunrise-sunset.com', - 'sunsgame.com', - 'sunumail.sn', - 'suomi24.fi', - 'superdada.com', - 'supereva.it', - 'supermail.ru', - 'superrito.com', - 'superstachel.de', - 'surat.com', - 'surf3.net', - 'surfree.com', - 'surfy.net', - 'surgical.net', - 'surimail.com', - 'survivormail.com', - 'susi.ml', - 'svk.jp', - 'swbell.net', - 'sweb.cz', - 'swedenmail.com', - 'sweetville.net', - 'sweetxxx.de', - 'swift-mail.com', - 'swiftdesk.com', - 'swingeasyhithard.com', - 'swingfan.com', - 'swipermail.zzn.com', - 'swirve.com', - 'swissinfo.org', - 'swissmail.com', - 'swissmail.net', - 'switchboardmail.com', - 'switzerland.org', - 'sx172.com', - 'syom.com', - 'syriamail.com', - 't-online.de', - 't.psh.me', - 't2mail.com', - 'tafmail.com', - 'takuyakimura.com', - 'talk21.com', - 'talkcity.com', - 'talkinator.com', - 'tamil.com', - 'tampabay.rr.com', - 'tankpolice.com', - 'tatanova.com', - 'tbwt.com', - 'tcc.on.ca', - 'tds.net', - 'teachermail.net', - 'teachers.org', - 'teamdiscovery.com', - 'teamtulsa.net', - 'tech-center.com', - 'tech4peace.org', - 'techemail.com', - 'techie.com', - 'technisamail.co.za', - 'technologist.com', - 'techscout.com', - 'techspot.com', - 'teenagedirtbag.com', - 'tele2.nl', - 'telebot.com', - 'telefonica.net', - 'teleline.es', - 'telenet.be', - 'telepac.pt', - 'telerymd.com', - 'teleworm.us', - 'telfort.nl', - 'telfortglasvezel.nl', - 'telinco.net', - 'telkom.net', - 'telpage.net', - 'telstra.com', - 'telstra.com.au', - 'temp-mail.com', - 'temp-mail.de', - 'temp.headstrong.de', - 'tempail.com', - 'tempemail.biz', - 'tempmail.us', - 'tempmail2.com', - 'tempmaildemo.com', - 'tempmailer.com', - 'temporarioemail.com.br', - 'temporaryemail.us', - 'tempthe.net', - 'tempymail.com', - 'temtulsa.net', - 'tenchiclub.com', - 'tenderkiss.com', - 'tennismail.com', - 'terminverpennt.de', - 'terra.cl', - 'terra.com', - 'terra.com.ar', - 'terra.com.br', - 'terra.es', - 'test.com', - 'test.de', - 'tfanus.com.er', - 'tfz.net', - 'thai.com', - 'thaimail.com', - 'thaimail.net', - 'thanksnospam.info', - 'the-african.com', - 'the-airforce.com', - 'the-aliens.com', - 'the-american.com', - 'the-animal.com', - 'the-army.com', - 'the-astronaut.com', - 'the-beauty.com', - 'the-big-apple.com', - 'the-biker.com', - 'the-boss.com', - 'the-brazilian.com', - 'the-canadian.com', - 'the-canuck.com', - 'the-captain.com', - 'the-chinese.com', - 'the-country.com', - 'the-cowboy.com', - 'the-davis-home.com', - 'the-dutchman.com', - 'the-eagles.com', - 'the-englishman.com', - 'the-fastest.net', - 'the-fool.com', - 'the-frenchman.com', - 'the-galaxy.net', - 'the-genius.com', - 'the-gentleman.com', - 'the-german.com', - 'the-gremlin.com', - 'the-hooligan.com', - 'the-italian.com', - 'the-japanese.com', - 'the-lair.com', - 'the-madman.com', - 'the-mailinglist.com', - 'the-marine.com', - 'the-master.com', - 'the-mexican.com', - 'the-ministry.com', - 'the-monkey.com', - 'the-newsletter.net', - 'the-pentagon.com', - 'the-police.com', - 'the-prayer.com', - 'the-professional.com', - 'the-quickest.com', - 'the-russian.com', - 'the-snake.com', - 'the-spaceman.com', - 'the-stock-market.com', - 'the-student.net', - 'the-whitehouse.net', - 'the-wild-west.com', - 'the18th.com', - 'thecoolguy.com', - 'thecriminals.com', - 'thedoghousemail.com', - 'thedorm.com', - 'theend.hu', - 'theglobe.com', - 'thegolfcourse.com', - 'thegooner.com', - 'theheadoffice.com', - 'theinternetemail.com', - 'thelanddownunder.com', - 'themail.com', - 'themillionare.net', - 'theoffice.net', - 'theplate.com', - 'thepokerface.com', - 'thepostmaster.net', - 'theraces.com', - 'theracetrack.com', - 'therapist.net', - 'thestreetfighter.com', - 'theteebox.com', - 'thewatercooler.com', - 'thewebpros.co.uk', - 'thewizzard.com', - 'thewizzkid.com', - 'thezhangs.net', - 'thirdage.com', - 'thisgirl.com', - 'thraml.com', - 'throwam.com', - 'thundermail.com', - 'tidni.com', - 'timein.net', - 'tiscali.at', - 'tiscali.be', - 'tiscali.co.uk', - 'tiscali.it', - 'tiscali.lu', - 'tiscali.se', - 'tkcity.com', - 'tmail.ws', - 'toast.com', - 'toke.com', - 'tom.com', - 'toolsource.com', - 'toomail.biz', - 'toothfairy.com', - 'topchat.com', - 'topgamers.co.uk', - 'topletter.com', - 'topmail-files.de', - 'topmail.com.ar', - 'topsurf.com', - 'torchmail.com', - 'torontomail.com', - 'tortenboxer.de', - 'totalmail.de', - 'totalmusic.net', - 'townisp.com', - 'tpg.com.au', - 'trash-amil.com', - 'trash-mail.ga', - 'trash-mail.ml', - 'trash2010.com', - 'trash2011.com', - 'trashdevil.de', - 'trashymail.net', - 'travel.li', - 'trayna.com', - 'trialbytrivia.com', - 'trickmail.net', - 'trimix.cn', - 'tritium.net', - 'trmailbox.com', - 'tropicalstorm.com', - 'truckerz.com', - 'truckracer.com', - 'truckracers.com', - 'trust-me.com', - 'truthmail.com', - 'tsamail.co.za', - 'ttml.co.in', - 'tunisiamail.com', - 'turboprinz.de', - 'turboprinzessin.de', - 'turkey.com', - 'turual.com', - 'tut.by', - 'tvstar.com', - 'twc.com', - 'twcny.com', - 'twinstarsmail.com', - 'tx.rr.com', - 'tycoonmail.com', - 'typemail.com', - 'u14269.ml', - 'u2club.com', - 'ua.fm', - 'uae.ac', - 'uaemail.com', - 'ubbi.com', - 'ubbi.com.br', - 'uboot.com', - 'uk2.net', - 'uk2k.com', - 'uk2net.com', - 'uk7.net', - 'uk8.net', - 'ukbuilder.com', - 'ukcool.com', - 'ukdreamcast.com', - 'ukmail.org', - 'ukmax.com', - 'ukr.net', - 'uku.co.uk', - 'ultra.fyi', - 'ultapulta.com', - 'ultrapostman.com', - 'ummah.org', - 'umpire.com', - 'unbounded.com', - 'unforgettable.com', - 'uni.de', - 'unican.es', - 'unihome.com', - 'unitybox.de', - 'universal.pt', - 'uno.ee', - 'uno.it', - 'unofree.it', - 'unterderbruecke.de', - 'uol.com.ar', - 'uol.com.br', - 'uol.com.co', - 'uol.com.mx', - 'uol.com.ve', - 'uole.com', - 'uole.com.ve', - 'uolmail.com', - 'uomail.com', - 'upc.nl', - 'upcmail.nl', - 'upf.org', - 'uplipht.com', - 'ureach.com', - 'urgentmail.biz', - 'urhen.com', - 'uroid.com', - 'usa.com', - 'usa.net', - 'usaaccess.net', - 'usanetmail.com', - 'used-product.fr', - 'usermail.com', - 'username.e4ward.com', - 'usma.net', - 'usmc.net', - 'uswestmail.net', - 'uymail.com', - 'uyuyuy.com', - 'v-sexi.com', - 'vaasfc4.tk', - 'vahoo.com', - 'valemail.net', - 'vampirehunter.com', - 'varbizmail.com', - 'vcmail.com', - 'velnet.co.uk', - 'velocall.com', - 'verizon.net', - 'verizonmail.com', - 'verlass-mich-nicht.de', - 'versatel.nl', - 'veryfast.biz', - 'veryrealemail.com', - 'veryspeedy.net', - 'vfemail.net', - 'vickaentb.tk', - 'videotron.ca', - 'viditag.com', - 'viewcastmedia.com', - 'viewcastmedia.net', - 'vinbazar.com', - 'violinmakers.co.uk', - 'vip.126.com', - 'vip.21cn.com', - 'vip.citiz.net', - 'vip.gr', - 'vip.onet.pl', - 'vip.qq.com', - 'vip.sina.com', - 'vipmail.ru', - 'virgilio.it', - 'virgin.net', - 'virginbroadband.com.au', - 'virginmedia.com', - 'virtualmail.com', - 'visitmail.com', - 'visitweb.com', - 'visto.com', - 'visualcities.com', - 'vivavelocity.com', - 'vivianhsu.net', - 'vjtimail.com', - 'vkcode.ru', - 'vnet.citiz.net', - 'vnn.vn', - 'vodafone.nl', - 'vodafonethuis.nl', - 'volcanomail.com', - 'vollbio.de', - 'volloeko.de', - 'vomoto.com', - 'vorsicht-bissig.de', - 'vorsicht-scharf.de', - 'vote-democrats.com', - 'vote-hillary.com', - 'vote-republicans.com', - 'vote4gop.org', - 'votenet.com', - 'vp.pl', - 'vr9.com', - 'vubby.com', - 'w3.to', - 'wahoye.com', - 'walala.org', - 'wales2000.net', - 'walkmail.net', - 'walkmail.ru', - 'wam.co.za', - 'wanadoo.es', - 'wanadoo.fr', - 'war-im-urlaub.de', - 'warmmail.com', - 'warpmail.net', - 'warrior.hu', - 'waumail.com', - 'wazabi.club', - 'wbdet.com', - 'wearab.net', - 'web-contact.info', - 'web-emailbox.eu', - 'web-ideal.fr', - 'web-mail.com.ar', - 'web-mail.pp.ua', - 'web-police.com', - 'web.de', - 'webave.com', - 'webcammail.com', - 'webcity.ca', - 'webcontact-france.eu', - 'webdream.com', - 'webindia123.com', - 'webjump.com', - 'webm4il.info', - 'webmail.co.yu', - 'webmail.co.za', - 'webmail.hu', - 'webmails.com', - 'webname.com', - 'webprogramming.com', - 'webstation.com', - 'websurfer.co.za', - 'webtopmail.com', - 'webuser.in', - 'wee.my', - 'weedmail.com', - 'weekmail.com', - 'weekonline.com', - 'wefjo.grn.cc', - 'weg-werf-email.de', - 'wegas.ru', - 'wegwerf-emails.de', - 'wegwerfmail.info', - 'wegwerpmailadres.nl', - 'wehshee.com', - 'weibsvolk.de', - 'weibsvolk.org', - 'weinenvorglueck.de', - 'welsh-lady.com', - 'westnet.com', - 'westnet.com.au', - 'wetrainbayarea.com', - 'wfgdfhj.tk', - 'whale-mail.com', - 'whartontx.com', - 'whatiaas.com', - 'whatpaas.com', - 'wheelweb.com', - 'whipmail.com', - 'whoever.com', - 'whoopymail.com', - 'whtjddn.33mail.com', - 'wi.rr.com', - 'wi.twcbc.com', - 'wickmail.net', - 'wideopenwest.com', - 'wildmail.com', - 'wilemail.com', - 'will-hier-weg.de', - 'windowslive.com', - 'windrivers.net', - 'windstream.net', - 'wingnutz.com', - 'winmail.com.au', - 'winning.com', - 'wir-haben-nachwuchs.de', - 'wir-sind-cool.org', - 'wirsindcool.de', - 'witty.com', - 'wiz.cc', - 'wkbwmail.com', - 'wmail.cf', - 'wo.com.cn', - 'woh.rr.com', - 'wolf-web.com', - 'wolke7.net', - 'wollan.info', - 'wombles.com', - 'women-at-work.org', - 'wongfaye.com', - 'wooow.it', - 'worker.com', - 'workmail.com', - 'worldemail.com', - 'worldnet.att.net', - 'wormseo.cn', - 'wosaddict.com', - 'wouldilie.com', - 'wovz.cu.cc', - 'wowgirl.com', - 'wowmail.com', - 'wowway.com', - 'wp.pl', - 'wptamail.com', - 'wrexham.net', - 'writeme.com', - 'writemeback.com', - 'wrongmail.com', - 'wtvhmail.com', - 'wwdg.com', - 'www.com', - 'www.e4ward.com', - 'www2000.net', - 'wx88.net', - 'wxs.net', - 'x-mail.net', - 'x-networks.net', - 'x5g.com', - 'xagloo.com', - 'xaker.ru', - 'xing886.uu.gl', - 'xmastime.com', - 'xms.nl', - 'xmsg.com', - 'xoom.com', - 'xoxox.cc', - 'xpressmail.zzn.com', - 'xs4all.nl', - 'xsecurity.org', - 'xsmail.com', - 'xtra.co.nz', - 'xuno.com', - 'xww.ro', - 'xy9ce.tk', - 'xyzfree.net', - 'xzapmail.com', - 'y7mail.com', - 'ya.ru', - 'yada-yada.com', - 'yaho.com', - 'yahoo.ae', - 'yahoo.at', - 'yahoo.be', - 'yahoo.ca', - 'yahoo.ch', - 'yahoo.cn', - 'yahoo.co', - 'yahoo.co.id', - 'yahoo.co.il', - 'yahoo.co.in', - 'yahoo.co.jp', - 'yahoo.co.kr', - 'yahoo.co.nz', - 'yahoo.co.th', - 'yahoo.co.uk', - 'yahoo.co.za', - 'yahoo.com', - 'yahoo.com.ar', - 'yahoo.com.au', - 'yahoo.com.br', - 'yahoo.com.cn', - 'yahoo.com.co', - 'yahoo.com.hk', - 'yahoo.com.is', - 'yahoo.com.mx', - 'yahoo.com.my', - 'yahoo.com.ph', - 'yahoo.com.ru', - 'yahoo.com.sg', - 'yahoo.com.tr', - 'yahoo.com.tw', - 'yahoo.com.vn', - 'yahoo.cz', - 'yahoo.de', - 'yahoo.dk', - 'yahoo.es', - 'yahoo.fi', - 'yahoo.fr', - 'yahoo.gr', - 'yahoo.hu', - 'yahoo.ie', - 'yahoo.in', - 'yahoo.it', - 'yahoo.jp', - 'yahoo.nl', - 'yahoo.no', - 'yahoo.pl', - 'yahoo.pt', - 'yahoo.ro', - 'yahoo.ru', - 'yahoo.se', - 'yahoofs.com', - 'yalla.com', - 'yalla.com.lb', - 'yalook.com', - 'yam.com', - 'yandex.com', - 'yandex.pl', - 'yandex.ru', - 'yandex.ua', - 'yapost.com', - 'yapped.net', - 'yawmail.com', - 'yeah.net', - 'yebox.com', - 'yehey.com', - 'yemenmail.com', - 'yepmail.net', - 'yert.ye.vc', - 'yesey.net', - 'yifan.net', - 'ymail.com', - 'yogotemail.com', - 'yomail.info', - 'yopmail.com', - 'yopmail.pp.ua', - 'yopolis.com', - 'yopweb.com', - 'youareadork.com', - 'youmailr.com', - 'your-house.com', - 'your-mail.com', - 'yourinbox.com', - 'yourlifesucks.cu.cc', - 'yourlover.net', - 'yourname.freeservers.com', - 'yournightmare.com', - 'yours.com', - 'yourssincerely.com', - 'yoursubdomain.zzn.com', - 'yourteacher.net', - 'yourwap.com', - 'yuuhuu.net', - 'yyhmail.com', - 'z1p.biz', - 'za.com', - 'zahadum.com', - 'zaktouni.fr', - 'zeepost.nl', - 'zetmail.com', - 'zhaowei.net', - 'zhouemail.510520.org', - 'ziggo.nl', - 'zionweb.org', - 'zip.net', - 'zipido.com', - 'ziplip.com', - 'zipmail.com', - 'zipmail.com.br', - 'zipmax.com', - 'zmail.ru', - 'zoemail.com', - 'zoemail.org', - 'zoho.com', - 'zohomail.com', - 'zomg.info', - 'zonnet.nl', - 'zoominternet.net', - 'zubee.com', - 'zuvio.com', - 'zuzzurello.com', - 'zwallet.com', - 'zweb.in', - 'zxcv.com', - 'zxcvbnm.com', - 'zybermail.com', - 'zydecofan.com', - 'zzn.com', - 'zzom.co.uk', - 'zzz.com', - 'zzz.pl' -] - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await sql` - CREATE TABLE IF NOT EXISTS "FreemailDomain" ( - "domain" VARCHAR(255) NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - PRIMARY KEY ("domain") - ); - `.execute(pg) - const values = HUBSPOT_FREEMAIL_DOMAINS.map((domain) => ({domain})) - await pg.insertInto('FreemailDomain').values(values).execute() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "FreemailDomain"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1695395426183_addAutoJoinToTeam.ts b/packages/server/postgres/migrations/1695395426183_addAutoJoinToTeam.ts deleted file mode 100644 index f897ab09ed8..00000000000 --- a/packages/server/postgres/migrations/1695395426183_addAutoJoinToTeam.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - ADD COLUMN "autoJoin" BOOLEAN NOT NULL DEFAULT FALSE; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - DROP COLUMN "autoJoin"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1696275124427_samlMetadataURL.ts b/packages/server/postgres/migrations/1696275124427_samlMetadataURL.ts deleted file mode 100644 index 3ee4f595bcf..00000000000 --- a/packages/server/postgres/migrations/1696275124427_samlMetadataURL.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "SAML" - ADD COLUMN IF NOT EXISTS "metadataURL" VARCHAR(2048); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "SAML" - DROP COLUMN IF EXISTS "metadataURL";`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1696443115482_addCustomerFeedbackTemplate.ts b/packages/server/postgres/migrations/1696443115482_addCustomerFeedbackTemplate.ts deleted file mode 100644 index f96e7641e37..00000000000 --- a/packages/server/postgres/migrations/1696443115482_addCustomerFeedbackTemplate.ts +++ /dev/null @@ -1,177 +0,0 @@ -import {PALETTE} from 'parabol-client/styles/paletteV3' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' -import getPgp from '../getPgp' - -interface Prompt { - question: string - description?: string -} - -interface Template { - name: string - type: 'feedback' - prompts: Prompt[] -} - -const NEW_TEMPLATE_CONFIGS: Template[] = [ - { - name: 'Customer feedback analysis', - type: 'feedback', - prompts: [ - { - question: 'What’s working for our customers?', - description: 'Share verbatim comments and/or observations' - }, - { - question: 'Where did our customers get stuck?', - description: 'Share verbatim comments and/or observations' - }, - { - question: 'What’s missing for our customers?', - description: 'Share verbatim comments and/or observations' - } - ] - } -] - -const createdAt = new Date() - -const makeId = (name: string, type: 'template' | 'prompt') => { - // FIXME truncate to 100 characters - const cleanedName = name - .replace(/[^0-9a-zA-Z ]/g, '') // remove emojis, apostrophes, and dashes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${type === 'template' ? 'Template' : 'Prompt'}` -} - -const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `Organization/aGhostOrg/template/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } else if (cdnType === 's3') { - const {CDN_BASE_URL} = process.env - if (!CDN_BASE_URL) throw new Error('Missng Env: CDN_BASE_URL') - const hostPath = CDN_BASE_URL.replace(/^\/+/, '') - return `https://${hostPath}/store/${partialPath}` - } - throw new Error('Mssing Env: FILE_STORE_PROVIDER') -} - -const makeTemplate = (template: Template) => ({ - createdAt, - id: makeId(template.name, 'template'), - isActive: true, - name: template.name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: false, - isFree: true, - illustrationUrl: getTemplateIllustrationUrl('whatWentWellTemplate.png'), - mainCategory: template.type, - lastUsedAt: null, - parentTemplateId: null -}) - -const promptColors = [PALETTE.GRAPE_500, PALETTE.AQUA_400, PALETTE.ROSE_500] - -type PromptInfo = { - question: string - description?: string - templateId: string - sortOrder: number -} - -const makePrompt = (promptInfo: PromptInfo, idx: number) => { - const {question, description, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColors[paletteIdx] - return { - createdAt, - description: description ?? '', - groupColor, - id: makeId(`${templateId}:${question}`, 'prompt'), - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - updatedAt: createdAt, - removedAt: null - } -} - -const templates = NEW_TEMPLATE_CONFIGS.map((templateConfig) => makeTemplate(templateConfig)) -let colorIndex = 0 -const reflectPrompts = NEW_TEMPLATE_CONFIGS.map((templateConfig) => { - return templateConfig.prompts.map((prompt, idx) => { - colorIndex++ - return makePrompt( - { - question: prompt.question, - description: prompt.description, - sortOrder: idx, - templateId: makeId(templateConfig.name, 'template') - }, - colorIndex - ) - }) -}).flat() - -export async function up() { - const {pgp, pg} = getPgp() - const columnSet = new pgp.helpers.ColumnSet( - [ - 'id', - 'createdAt', - 'isActive', - 'name', - 'teamId', - 'updatedAt', - 'scope', - 'orgId', - 'type', - 'illustrationUrl', - 'mainCategory', - {name: 'isStarter', def: false}, - {name: 'isFree', def: false} - ], - {table: 'MeetingTemplate'} - ) - const insert = pgp.helpers.insert(templates, columnSet) - await pg.none(insert) - try { - await connectRethinkDB() - await r.table('ReflectPrompt').insert(reflectPrompts).run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export async function down() { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await connectRethinkDB() - await r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = ANY($1);`, [templateIds]) - await client.end() -} diff --git a/packages/server/postgres/migrations/1696616922662_addPeerReviewTemplates.ts b/packages/server/postgres/migrations/1696616922662_addPeerReviewTemplates.ts deleted file mode 100644 index f32f9ce5262..00000000000 --- a/packages/server/postgres/migrations/1696616922662_addPeerReviewTemplates.ts +++ /dev/null @@ -1,249 +0,0 @@ -import {PALETTE} from 'parabol-client/styles/paletteV3' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' -import getPgp from '../getPgp' - -interface Prompt { - question: string - description?: string -} - -interface Template { - name: string - type: 'feedback' - illustration: string - prompts: Prompt[] -} - -const NEW_TEMPLATE_CONFIGS: Template[] = [ - { - name: '360 Review: Open-ended Feedback', - type: 'feedback', - illustration: 'heardSeenRespectedHSRTemplate.png', - prompts: [ - { - question: 'Trust', - description: - 'What examples can you give that have helped or hurt you trust this colleague’s ability to assist you with your own work?' - }, - { - question: 'In Focus', - description: - 'What appears to have this colleague’s attention over other efforts? Give some examples.' - }, - { - question: 'Out of Focus', - description: 'What isn’t getting as much attention as perhaps it should?' - }, - { - question: 'Values', - description: 'Share examples of a company value this person has brought to life.' - }, - { - question: 'Questions', - description: - 'What questions might you have about the work of the role(s) this colleague performs?' - } - ] - }, - { - name: '360 Review: Feedback on Progression', - type: 'feedback', - illustration: 'mountainClimberTemplate.png', - prompts: [ - { - question: 'Roles & Skills', - description: - 'What should this colleague do more of or less of to grow professionally or better the company?' - }, - { - question: 'Collaboration', - description: - 'What should this colleague stop, start, or continue doing when working alongside others?' - }, - { - question: 'People Matters', - description: - 'How has this colleague best helped develop others around them? How can they do better? What should they stop?' - }, - { - question: 'Questions', - description: - 'What questions do you have about this colleague’s roles, work, development, or performance in general?' - } - ] - }, - { - name: '360 Review: Feedback on Development', - type: 'feedback', - illustration: 'hopesAndFearsTemplate.png', - prompts: [ - { - question: 'Remarkable', - description: - 'What does this colleague do that you find remarkable? What do you brag about them to other people?' - }, - { - question: 'Obstacles', - description: 'What do you see getting in this colleague’s way?' - }, - { - question: 'Challenges', - description: - 'Assume you’re working with this colleague for the next 10 years. What behavior isn’t a big deal now, but will get challenging over that time?' - }, - { - question: 'Opportunities', - description: - 'What areas would you like to see this colleague develop in? How could they be more helpful to you or the organization?' - } - ] - } -] - -const createdAt = new Date() - -const makeId = (name: string, type: 'template' | 'prompt') => { - // FIXME truncate to 100 characters - const cleanedName = name - .replace(/[^0-9a-zA-Z ]/g, '') // remove emojis, apostrophes, and dashes - .split(' ') - .map( - (name, idx) => - (idx === 0 ? name.charAt(0).toLowerCase() : name.charAt(0).toUpperCase()) + name.slice(1) - ) - .join('') - .trim() - return `${cleanedName}${type === 'template' ? 'Template' : 'Prompt'}` -} - -const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `Organization/aGhostOrg/template/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } else if (cdnType === 's3') { - const {CDN_BASE_URL} = process.env - if (!CDN_BASE_URL) throw new Error('Missng Env: CDN_BASE_URL') - const hostPath = CDN_BASE_URL.replace(/^\/+/, '') - return `https://${hostPath}/store/${partialPath}` - } - throw new Error('Mssing Env: FILE_STORE_PROVIDER') -} - -const makeTemplate = (template: Template) => ({ - createdAt, - id: makeId(template.name, 'template'), - isActive: true, - name: template.name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'retrospective', - updatedAt: createdAt, - isStarter: false, - isFree: true, - illustrationUrl: getTemplateIllustrationUrl(template.illustration), - mainCategory: template.type, - lastUsedAt: null, - parentTemplateId: null -}) - -const promptColors = [ - PALETTE.GRAPE_500, - PALETTE.AQUA_400, - PALETTE.ROSE_500, - PALETTE.JADE_400, - PALETTE.TERRA_300 -] - -type PromptInfo = { - question: string - description?: string - templateId: string - sortOrder: number -} - -const makePrompt = (promptInfo: PromptInfo, idx: number) => { - const {question, description, templateId, sortOrder} = promptInfo - const paletteIdx = idx > promptColors.length - 1 ? idx % promptColors.length : idx - const groupColor = promptColors[paletteIdx] - return { - createdAt, - description: description ?? '', - groupColor, - id: makeId(`${templateId}:${question}`, 'prompt'), - question, - sortOrder, - teamId: 'aGhostTeam', - templateId, - updatedAt: createdAt, - removedAt: null - } -} - -const templates = NEW_TEMPLATE_CONFIGS.map((templateConfig) => makeTemplate(templateConfig)) -let colorIndex = 0 -const reflectPrompts = NEW_TEMPLATE_CONFIGS.map((templateConfig) => { - return templateConfig.prompts.map((prompt, idx) => { - colorIndex++ - return makePrompt( - { - question: prompt.question, - description: prompt.description, - sortOrder: idx, - templateId: makeId(templateConfig.name, 'template') - }, - colorIndex - ) - }) -}).flat() - -export async function up() { - const {pgp, pg} = getPgp() - const columnSet = new pgp.helpers.ColumnSet( - [ - 'id', - 'createdAt', - 'isActive', - 'name', - 'teamId', - 'updatedAt', - 'scope', - 'orgId', - 'type', - 'illustrationUrl', - 'mainCategory', - {name: 'isStarter', def: false}, - {name: 'isFree', def: false} - ], - {table: 'MeetingTemplate'} - ) - const insert = pgp.helpers.insert(templates, columnSet) - await pg.none(insert) - try { - await connectRethinkDB() - await r.table('ReflectPrompt').insert(reflectPrompts).run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export async function down() { - const templateIds = templates.map(({id}) => id) - const promptIds = reflectPrompts.map(({id}) => id) - try { - await connectRethinkDB() - await r.table('ReflectPrompt').getAll(r.args(promptIds)).delete().run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = ANY($1);`, [templateIds]) - await client.end() -} diff --git a/packages/server/postgres/migrations/1697477646986_swot-typo.ts b/packages/server/postgres/migrations/1697477646986_swot-typo.ts deleted file mode 100644 index 73c656b4922..00000000000 --- a/packages/server/postgres/migrations/1697477646986_swot-typo.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {r} from 'rethinkdb-ts' - -const connectRethinkDB = async () => { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) -} - -export async function up() { - await connectRethinkDB() - await r - .table('ReflectPrompt') - .get('sWOTAnalysisTemplate:stengthsPrompt') - .update({question: 'Strengths'}) - .run() -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1698264242460_renameUserSegmentIdToPseudoId.ts b/packages/server/postgres/migrations/1698264242460_renameUserSegmentIdToPseudoId.ts deleted file mode 100644 index a50e28202bb..00000000000 --- a/packages/server/postgres/migrations/1698264242460_renameUserSegmentIdToPseudoId.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - RENAME COLUMN "segmentId" TO "pseudoId"; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - RENAME COLUMN "pseudoId" TO "segmentId"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1698265572466_renameEmailVerificationSegmentIdToPseudoId.ts b/packages/server/postgres/migrations/1698265572466_renameEmailVerificationSegmentIdToPseudoId.ts deleted file mode 100644 index 694fa70b2fb..00000000000 --- a/packages/server/postgres/migrations/1698265572466_renameEmailVerificationSegmentIdToPseudoId.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {r, RDatum} from 'rethinkdb-ts' - -const connectRethinkDB = async () => { - const {hostname: host, port, pathname} = new URL(process.env.RETHINKDB_URL!) - await r.connectPool({ - host, - port: parseInt(port, 10), - db: pathname.split('/')[1] - }) -} - -export async function up() { - await connectRethinkDB() - await r - .table('EmailVerification') - .replace((row: RDatum) => row.without('segmentId').merge({pseudoId: row('segmentId')})) - .run() -} - -export async function down() { - await connectRethinkDB() - await r - .table('EmailVerification') - .replace((row: RDatum) => row.without('pseudoId').merge({segmentId: row('pseudoId')})) - .run() -} diff --git a/packages/server/postgres/migrations/1698265600000_addPrioritizationTemplates.ts b/packages/server/postgres/migrations/1698265600000_addPrioritizationTemplates.ts deleted file mode 100644 index b91e51a285c..00000000000 --- a/packages/server/postgres/migrations/1698265600000_addPrioritizationTemplates.ts +++ /dev/null @@ -1,210 +0,0 @@ -import {PALETTE} from 'parabol-client/styles/paletteV3' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' -import getPgp from '../getPgp' - -const createdAt = new Date() - -interface ScaleValue { - color: string - label: string -} - -interface Scale { - id: string - name: string - values: ScaleValue[] -} - -interface Dimension { - id: string - name: string - scaleId: string -} - -interface Template { - id: string - name: string - dimensions: Dimension[] -} - -const getTemplateIllustrationUrl = (filename: string) => { - const cdnType = process.env.FILE_STORE_PROVIDER - const partialPath = `Organization/aGhostOrg/template/${filename}` - if (cdnType === 'local') { - return `/self-hosted/${partialPath}` - } else if (cdnType === 's3') { - const {CDN_BASE_URL} = process.env - if (!CDN_BASE_URL) throw new Error('Missng Env: CDN_BASE_URL') - const hostPath = CDN_BASE_URL.replace(/^\/+/, '') - return `https://${hostPath}/store/${partialPath}` - } - throw new Error('Mssing Env: FILE_STORE_PROVIDER') -} - -const MOSCOW_SCALE_CONFIG = { - createdAt, - id: 'moscowScale', - isStarter: true, - name: 'MoSCoW', - sortOrder: 4, - teamId: 'aGhostTeam', - updatedAt: createdAt, - values: [ - {label: 'M', color: PALETTE.TOMATO_500}, - {label: 'S', color: PALETTE.TERRA_300}, - {label: 'C', color: PALETTE.GOLD_300}, - {label: 'W', color: PALETTE.GRASS_300}, - {label: '?', color: PALETTE.ROSE_500}, - {label: 'Pass', color: PALETTE.GRAPE_500} - ] -} - -const NEW_TEMPLATE_CONFIGS: Template[] = [ - { - id: 'moscowPrioritizationTemplate', - name: 'MoSCoW Prioritization', - dimensions: [ - { - id: 'moscowPriorityDimension', - name: 'Priority? Must/Should/Could/Won’t Have', - scaleId: 'moscowScale' - } - ] - }, - { - id: 'ricePrioritizationTemplate', - name: 'RICE Prioritization', - dimensions: [ - { - id: 'riceReachDimension', - name: 'Reach', - scaleId: 'fiveFingersScale' - }, - { - id: 'riceImpactDimension', - name: 'Impact', - scaleId: 'fiveFingersScale' - }, - { - id: 'riceConfidenceDimension', - name: 'Confidence', - scaleId: 'fiveFingersScale' - }, - { - id: 'riceEffortDimension', - name: 'Effort', - scaleId: 'fiveFingersScale' - } - ] - } -] - -const scales = [MOSCOW_SCALE_CONFIG] - -const makeTemplate = (template: Template) => ({ - createdAt, - id: template.id, - isActive: true, - name: template.name, - orgId: 'aGhostOrg', - scope: 'PUBLIC', - teamId: 'aGhostTeam', - type: 'poker', - updatedAt: createdAt, - isStarter: true, - isFree: true, - illustrationUrl: getTemplateIllustrationUrl('newTemplate.png'), - mainCategory: 'strategy', - lastUsedAt: null, - parentTemplateId: null -}) - -const templates = NEW_TEMPLATE_CONFIGS.map((templateConfig) => makeTemplate(templateConfig)) - -type DimensionInfo = { - id: string - name: string - scaleId: string - sortOrder: number - templateId: string -} - -const makeDimension = (dimensionInfo: DimensionInfo) => { - const {id, name, scaleId, sortOrder, templateId} = dimensionInfo - return { - createdAt, - description: '', - id, - name, - scaleId, - sortOrder, - teamId: 'aGhostTeam', - templateId, - updatedAt: createdAt - } -} - -const dimensions = NEW_TEMPLATE_CONFIGS.map((templateConfig) => { - return templateConfig.dimensions.map((dimension, idx) => { - return makeDimension({ - id: dimension.id, - name: dimension.name, - scaleId: dimension.scaleId, - sortOrder: idx, - templateId: templateConfig.id - }) - }) -}).flat() - -export async function up() { - const {pgp, pg} = getPgp() - const columnSet = new pgp.helpers.ColumnSet( - [ - 'id', - 'createdAt', - 'isActive', - 'name', - 'teamId', - 'updatedAt', - 'scope', - 'orgId', - 'type', - 'illustrationUrl', - 'mainCategory', - {name: 'isStarter', def: false}, - {name: 'isFree', def: false} - ], - {table: 'MeetingTemplate'} - ) - const insert = pgp.helpers.insert(templates, columnSet) - await pg.none(insert) - try { - await connectRethinkDB() - await r.table('TemplateDimension').insert(dimensions).run() - await r.table('TemplateScale').insert(scales).run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export async function down() { - const templateIds = templates.map(({id}) => id) - const dimensionIds = dimensions.map(({id}) => id) - const scaleIds = scales.map(({id}) => id) - try { - await connectRethinkDB() - await r.table('TemplateDimension').getAll(r.args(dimensionIds)).delete().run() - await r.table('TemplateScale').getAll(r.args(scaleIds)).delete().run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "MeetingTemplate" WHERE id = ANY($1);`, [templateIds]) - await client.end() -} diff --git a/packages/server/postgres/migrations/1698831891828_moreFreeRetroTemplates.ts b/packages/server/postgres/migrations/1698831891828_moreFreeRetroTemplates.ts deleted file mode 100644 index c7e5dc5ee76..00000000000 --- a/packages/server/postgres/migrations/1698831891828_moreFreeRetroTemplates.ts +++ /dev/null @@ -1,51 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -const FREE_TEMPLATES = [ - 'aChristmasCarolRetrospectiveTemplate', - 'diwaliRetrospectiveTemplate', - 'dropAddKeepImproveDAKITemplate', - 'easterRetrospectiveTemplate', - 'energyLevelsTemplate', - 'halloweenRetrospectiveTemplate', - 'holiRetrospectiveTemplate', - 'keepProblemTryTemplate', - 'leanCoffeeTemplate', - 'lunarNewYearRetrospectiveTemplate', - 'midsummerRetrospectiveTemplate', - 'mountainClimberTemplate', - 'newYearRetrospectiveTemplate', - 'sWOTAnalysisTemplate', - 'teamCharterTemplate', - 'teamRetreatPlanningTemplate', - 'thanksgivingRetrospectiveTemplate', - 'threeLittlePigsTemplate' -] - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query( - ` - UPDATE "MeetingTemplate" - SET "isFree" = true - WHERE id = ANY ($1) - `, - [FREE_TEMPLATES] - ) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query( - ` - UPDATE "MeetingTemplate" - SET "isFree" = false - WHERE id = ANY ($1) - `, - [FREE_TEMPLATES] - ) - await client.end() -} diff --git a/packages/server/postgres/migrations/1699394201062_trialColumns.ts b/packages/server/postgres/migrations/1699394201062_trialColumns.ts deleted file mode 100644 index 303a6cf157f..00000000000 --- a/packages/server/postgres/migrations/1699394201062_trialColumns.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - ADD COLUMN "trialStartDate" TIMESTAMP WITH TIME ZONE; - ALTER TABLE "Team" - ADD COLUMN "trialStartDate" TIMESTAMP WITH TIME ZONE; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "User" - DROP COLUMN "trialStartDate"; - ALTER TABLE "Team" - DROP COLUMN "trialStartDate"`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1699448432969_teamKudosSettings.ts b/packages/server/postgres/migrations/1699448432969_teamKudosSettings.ts deleted file mode 100644 index 01489be9bb7..00000000000 --- a/packages/server/postgres/migrations/1699448432969_teamKudosSettings.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "giveKudosWithEmoji" BOOLEAN NOT NULL DEFAULT TRUE, - ADD COLUMN IF NOT EXISTS "kudosEmoji" TEXT NOT NULL DEFAULT 'heart'; - END - $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - DROP COLUMN "giveKudosWithEmoji", - DROP COLUMN "kudosEmoji"; - END - $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1699561055400_addKudosesTable.ts b/packages/server/postgres/migrations/1699561055400_addKudosesTable.ts deleted file mode 100644 index 156447dece0..00000000000 --- a/packages/server/postgres/migrations/1699561055400_addKudosesTable.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "Kudos" ( - "id" SERIAL PRIMARY KEY, - "senderUserId" VARCHAR(100) NOT NULL, - "receiverUserId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "reactableId" VARCHAR(100), - "reactableType" VARCHAR(50), - "emoji" VARCHAR(100), - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - FOREIGN KEY("senderUserId") - REFERENCES "User"("id") - ON DELETE CASCADE, - FOREIGN KEY("receiverUserId") - REFERENCES "User"("id") - ON DELETE CASCADE, - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - - DROP TRIGGER IF EXISTS "update_Kudos_updatedAt" ON "Kudos"; - CREATE TRIGGER "update_Kudos_updatedAt" BEFORE UPDATE ON "Kudos" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "Kudos"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1701679264301_storeUnicodeEmojiForKudos.ts b/packages/server/postgres/migrations/1701679264301_storeUnicodeEmojiForKudos.ts deleted file mode 100644 index e0710e27e60..00000000000 --- a/packages/server/postgres/migrations/1701679264301_storeUnicodeEmojiForKudos.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "kudosEmojiUnicode" VARCHAR(100) NOT NULL DEFAULT '❤️'; - ALTER TABLE "Kudos" - ADD COLUMN IF NOT EXISTS "emojiUnicode" VARCHAR(100) NOT NULL DEFAULT '❤️'; - END - $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - DROP COLUMN "kudosEmojiUnicode"; - ALTER TABLE "Kudos" - DROP COLUMN "emojiUnicode"; - END - $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1701769672206_kudosTeamPromptResponseId.ts b/packages/server/postgres/migrations/1701769672206_kudosTeamPromptResponseId.ts deleted file mode 100644 index dc2cb4e381a..00000000000 --- a/packages/server/postgres/migrations/1701769672206_kudosTeamPromptResponseId.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Kudos" - DROP CONSTRAINT IF EXISTS "fk_teamPromptResponseId"; - - ALTER TABLE "Kudos" - ADD COLUMN IF NOT EXISTS "teamPromptResponseId" INT, - ADD CONSTRAINT "fk_teamPromptResponseId" - FOREIGN KEY("teamPromptResponseId") - REFERENCES "TeamPromptResponse"("id") - ON DELETE CASCADE; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Kudos" - DROP COLUMN IF EXISTS "teamPromptResponseId"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1702642769291_isAnonymousKudos.ts b/packages/server/postgres/migrations/1702642769291_isAnonymousKudos.ts deleted file mode 100644 index 4193ebfd3ed..00000000000 --- a/packages/server/postgres/migrations/1702642769291_isAnonymousKudos.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Kudos" - ADD COLUMN IF NOT EXISTS "isAnonymous" BOOLEAN NOT NULL DEFAULT FALSE, - ADD COLUMN IF NOT EXISTS "reflectionId" VARCHAR(100); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Kudos" - DROP COLUMN "isAnonymous", - DROP COLUMN "reflectionId"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1703031300000_addEmbeddingTables.ts b/packages/server/postgres/migrations/1703031300000_addEmbeddingTables.ts deleted file mode 100644 index 33718ee75a1..00000000000 --- a/packages/server/postgres/migrations/1703031300000_addEmbeddingTables.ts +++ /dev/null @@ -1,93 +0,0 @@ -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'EmbeddingsObjectTypeEnum') THEN - EXECUTE 'CREATE TYPE "EmbeddingsObjectTypeEnum" AS ENUM (''retrospectiveDiscussionTopic'')'; - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'EmbeddingsStateEnum') THEN - EXECUTE 'CREATE TYPE "EmbeddingsStateEnum" AS ENUM (''queued'', ''embedding'', ''failed'')'; - END IF; - - EXECUTE 'CREATE TABLE IF NOT EXISTS "EmbeddingsMetadata" ( - "id" SERIAL PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "objectType" "EmbeddingsObjectTypeEnum" NOT NULL, - "refId" VARCHAR(100), - UNIQUE("objectType", "refId"), - "refUpdatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "models" VARCHAR(255)[], - "teamId" VARCHAR(100) NOT NULL, - "embedText" TEXT - )'; - - DROP TRIGGER IF EXISTS "update_EmbeddingsMetadata_updatedAt" ON "EmbeddingsMetadata"; - CREATE TRIGGER "update_EmbeddingsMetadata_updatedAt" BEFORE UPDATE ON "EmbeddingsMetadata" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsMetadata_objectType" ON "EmbeddingsMetadata"("objectType")'; - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsMetadata_refUpdatedAt" ON "EmbeddingsMetadata"("refUpdatedAt")'; - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsMetadata_models" ON "EmbeddingsMetadata" USING GIN (models)'; - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsMetadata_teamId" ON "EmbeddingsMetadata"("teamId")'; - - EXECUTE 'CREATE TABLE IF NOT EXISTS "EmbeddingsJobQueue" ( - "id" SERIAL PRIMARY KEY, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "objectType" "EmbeddingsObjectTypeEnum" NOT NULL, - "refId" VARCHAR(100) NOT NULL, - "model" VARCHAR(255) NOT NULL, - UNIQUE("objectType", "refId", "model"), - "state" "EmbeddingsStateEnum" DEFAULT ''queued'' NOT NULL, - "stateMessage" TEXT - )'; - - DROP TRIGGER IF EXISTS "update_EmbeddingsJobQueue_updatedAt" ON "EmbeddingsJobQueue"; - CREATE TRIGGER "update_EmbeddingsJobQueue_updatedAt" BEFORE UPDATE ON "EmbeddingsJobQueue" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsJobQueue_objectType" ON "EmbeddingsJobQueue"("objectType")'; - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsJobQueue_refId" ON "EmbeddingsJobQueue"("refId")'; - EXECUTE 'CREATE INDEX IF NOT EXISTS "idx_EmbeddingsJobQueue_state" ON "EmbeddingsJobQueue"("state")'; - END $$; - `) - await client.end() - try { - await connectRethinkDB() - await r - .table('Organization') - .indexCreate('featureFlagsIndex', r.row('featureFlags'), {multi: true}) - .run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - EXECUTE 'DROP TABLE IF EXISTS "EmbeddingsJobQueue"'; - EXECUTE 'DROP TABLE IF EXISTS "EmbeddingsMetadata"'; - - EXECUTE 'DROP TYPE IF EXISTS "EmbeddingsStateEnum" CASCADE'; - EXECUTE 'DROP TYPE IF EXISTS "EmbeddingsObjectTypeEnum" CASCADE'; - END $$; - `) - await client.end() - try { - await connectRethinkDB() - await r.table('Organization').indexDrop('featureFlagsIndex').run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} diff --git a/packages/server/postgres/migrations/1706021181176_addGCalEventToMeetingSeries.ts b/packages/server/postgres/migrations/1706021181176_addGCalEventToMeetingSeries.ts deleted file mode 100644 index 919dda62a87..00000000000 --- a/packages/server/postgres/migrations/1706021181176_addGCalEventToMeetingSeries.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "MeetingSeries" - ADD COLUMN IF NOT EXISTS "gcalSeriesId" VARCHAR(100); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "MeetingSeries" - DROP COLUMN IF EXISTS "gcalSeriesId"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1708127504000_updateEmbeddingMetadata.ts b/packages/server/postgres/migrations/1708127504000_updateEmbeddingMetadata.ts deleted file mode 100644 index 279dd6f90b7..00000000000 --- a/packages/server/postgres/migrations/1708127504000_updateEmbeddingMetadata.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - try { - await client.query(` - ALTER TABLE "EmbeddingsMetadata" RENAME COLUMN "embedText" TO "fullText"; - `) - } catch { - // noop - } - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "EmbeddingsMetadata" RENAME COLUMN "fullText" TO "embedText"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1709551949071_makeAllTemplatesFree.ts b/packages/server/postgres/migrations/1709551949071_makeAllTemplatesFree.ts deleted file mode 100644 index 25bc6553255..00000000000 --- a/packages/server/postgres/migrations/1709551949071_makeAllTemplatesFree.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query( - ` - UPDATE "MeetingTemplate" - SET "isFree" = true - WHERE "orgId" = 'aGhostOrg' - ` - ) - - await client.end() -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1709927369000_addFailedAuthRequest.ts b/packages/server/postgres/migrations/1709927369000_addFailedAuthRequest.ts deleted file mode 100644 index b58461c7b94..00000000000 --- a/packages/server/postgres/migrations/1709927369000_addFailedAuthRequest.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE "FailedAuthRequest" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "email" "citext" NOT NULL, - "ip" "inet" NOT NULL, - "time" TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL - ); - - CREATE INDEX IF NOT EXISTS "idx_FailedAuthRequest_email" ON "FailedAuthRequest"("email"); - CREATE INDEX IF NOT EXISTS "idx_FailedAuthRequest_ip" ON "FailedAuthRequest"("ip"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "FailedAuthRequest"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1709927822000_addScheduledJob.ts b/packages/server/postgres/migrations/1709927822000_addScheduledJob.ts deleted file mode 100644 index dffd9217014..00000000000 --- a/packages/server/postgres/migrations/1709927822000_addScheduledJob.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ScheduledJobTypeEnum') THEN - EXECUTE 'CREATE TYPE "ScheduledJobTypeEnum" AS ENUM (''MEETING_STAGE_TIME_LIMIT_END'', ''LOCK_ORGANIZATION'', ''WARN_ORGANIZATION'')'; - END IF; - END $$; - - CREATE TABLE "ScheduledJob" ( - "id" SERIAL PRIMARY KEY, - "runAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, - "type" "ScheduledJobTypeEnum" NOT NULL, - "orgId" VARCHAR(100), - "meetingId" VARCHAR(100) - ); - - CREATE INDEX IF NOT EXISTS "idx_ScheduledJob_orgId" ON "ScheduledJob"("orgId"); - CREATE INDEX IF NOT EXISTS "idx_ScheduledJob_runAt" ON "ScheduledJob"("runAt"); - CREATE INDEX IF NOT EXISTS "idx_ScheduledJob_type" ON "ScheduledJob"("type"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "ScheduledJob"; - DROP TYPE IF EXISTS "ScheduledJobTypeEnum"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1709927835000_moveScheduledJob.ts b/packages/server/postgres/migrations/1709927835000_moveScheduledJob.ts deleted file mode 100644 index c46bc4b045a..00000000000 --- a/packages/server/postgres/migrations/1709927835000_moveScheduledJob.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {FirstParam} from 'parabol-client/types/generics' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPgConfig from '../getPgConfig' -import getPgp from '../getPgp' - -export async function up() { - await connectRethinkDB() - const {pgp, pg} = getPgp() - const batchSize = 1000 - - const columnSet = new pgp.helpers.ColumnSet( - ['runAt', 'type', {name: 'orgId', def: null}, {name: 'meetingId', def: null}], - {table: 'ScheduledJob'} - ) - - const getNextData = async (leftBoundCursor: Date | undefined) => { - const startAt = leftBoundCursor || r.minval - const nextBatch = await r - .table('ScheduledJob') - .between(startAt, r.maxval, {index: 'runAt', leftBound: 'open'}) - .orderBy({index: 'runAt'}) - .limit(batchSize) - .run() - if (nextBatch.length === 0) return null - if (nextBatch.length < batchSize) return nextBatch - const lastItem = nextBatch.pop() - const lastMatchingRunAt = nextBatch.findLastIndex((item) => item.runAt !== lastItem!.runAt) - if (lastMatchingRunAt === -1) { - throw new Error( - 'batchSize is smaller than the number of items that share the same cursor. Increase batchSize' - ) - } - return nextBatch.slice(0, lastMatchingRunAt) - } - - await pg.tx('ScheduledJob', (task) => { - const fetchAndProcess: FirstParam = async ( - _index, - leftBoundCursor: undefined | Date - ) => { - const nextData = await getNextData(leftBoundCursor) - if (!nextData) return undefined - const insert = pgp.helpers.insert(nextData, columnSet) - await task.none(insert) - return nextData.at(-1)!.runAt - } - return task.sequence(fetchAndProcess) - }) - await r.getPoolMaster()?.drain() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`DELETE FROM "ScheduledJob"`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1709933510512_addFreeCustomTemplatesRemaining.ts b/packages/server/postgres/migrations/1709933510512_addFreeCustomTemplatesRemaining.ts deleted file mode 100644 index fd2ceae8931..00000000000 --- a/packages/server/postgres/migrations/1709933510512_addFreeCustomTemplatesRemaining.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema - .alterTable('User') - .addColumn('freeCustomRetroTemplatesRemaining', 'int2', (col) => col.defaultTo(2).notNull()) - .addColumn('freeCustomPokerTemplatesRemaining', 'int2', (col) => col.defaultTo(2).notNull()) - .execute() -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema - .alterTable('User') - .dropColumn('freeCustomRetroTemplatesRemaining') - .dropColumn('freeCustomPokerTemplatesRemaining') - .execute() -} diff --git a/packages/server/postgres/migrations/1709934935000_embeddingsMetadataId.ts b/packages/server/postgres/migrations/1709934935000_embeddingsMetadataId.ts deleted file mode 100644 index 185b1e0881b..00000000000 --- a/packages/server/postgres/migrations/1709934935000_embeddingsMetadataId.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - // wipe data to ensure the non-null constraints succeed - await client.query(` - CREATE TYPE "ISO6391Enum" AS ENUM ('aa', 'ab', 'af', 'ak', 'am', 'ar', 'an', 'as', 'av', 'ae', 'ay', 'az', 'ba', 'bm', 'be', 'bn', 'bi', 'bo', 'bs', 'br', 'bg', 'ca', 'cs', 'ch', 'ce', 'cu', 'cv', 'kw', 'co', 'cr', 'cy', 'da', 'de', 'dv', 'dz', 'el', 'en', 'eo', 'et', 'eu', 'ee', 'fo', 'fa', 'fj', 'fi', 'fr', 'fy', 'ff', 'gd', 'ga', 'gl', 'gv', 'gn', 'gu', 'ht', 'ha', 'sh', 'he', 'hz', 'hi', 'ho', 'hr', 'hu', 'hy', 'ig', 'io', 'ii', 'iu', 'ie', 'ia', 'id', 'ik', 'is', 'it', 'jv', 'ja', 'kl', 'kn', 'ks', 'ka', 'kr', 'kk', 'km', 'ki', 'rw', 'ky', 'kv', 'kg', 'ko', 'kj', 'ku', 'lo', 'la', 'lv', 'li', 'ln', 'lt', 'lb', 'lu', 'lg', 'mh', 'ml', 'mr', 'mk', 'mg', 'mt', 'mn', 'mi', 'ms', 'my', 'na', 'nv', 'nr', 'nd', 'ng', 'ne', 'nl', 'nn', 'nb', 'no', 'ny', 'oc', 'oj', 'or', 'om', 'os', 'pa', 'pi', 'pl', 'pt', 'ps', 'qu', 'rm', 'ro', 'rn', 'ru', 'sg', 'sa', 'si', 'sk', 'sl', 'se', 'sm', 'sn', 'sd', 'so', 'st', 'es', 'sq', 'sc', 'sr', 'ss', 'su', 'sw', 'sv', 'ty', 'ta', 'tt', 'te', 'tg', 'tl', 'th', 'ti', 'to', 'tn', 'ts', 'tk', 'tr', 'tw', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu'); - DELETE FROM "EmbeddingsMetadata"; - DELETE FROM "EmbeddingsJobQueue"; - CREATE INDEX IF NOT EXISTS "idx_Discussion_createdAt" ON "Discussion"("createdAt"); - ALTER TYPE "EmbeddingsStateEnum" RENAME VALUE 'embedding' TO 'running'; - ALTER TYPE "EmbeddingsStateEnum" RENAME TO "EmbeddingsJobStateEnum"; - ALTER TABLE "EmbeddingsMetadata" - DROP COLUMN "models", - ADD COLUMN "language" "ISO6391Enum", - ALTER COLUMN "refId" SET NOT NULL; - ALTER TABLE "EmbeddingsJobQueue" - ADD COLUMN "retryAfter" TIMESTAMP WITH TIME ZONE, - ADD COLUMN "retryCount" SMALLINT NOT NULL DEFAULT 0, - ADD COLUMN "startAt" TIMESTAMP WITH TIME ZONE, - ADD COLUMN "priority" SMALLINT NOT NULL DEFAULT 50, - ADD COLUMN "jobData" JSONB NOT NULL DEFAULT '{}', - ADD COLUMN "jobType" VARCHAR(255) NOT NULL, - DROP CONSTRAINT IF EXISTS "EmbeddingsJobQueue_objectType_refId_model_key", - DROP COLUMN "refId", - DROP COLUMN "objectType", - DROP COLUMN "model"; - CREATE INDEX IF NOT EXISTS "idx_EmbeddingsJobQueue_priority" ON "EmbeddingsJobQueue"("priority"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TYPE IF EXISTS "ISO6391Enum" CASCADE; - DROP INDEX IF EXISTS "idx_Discussion_createdAt"; - ALTER TYPE "EmbeddingsJobStateEnum" RENAME VALUE 'running' TO 'embedding'; - ALTER TYPE "EmbeddingsJobStateEnum" RENAME TO "EmbeddingsStateEnum"; - ALTER TABLE "EmbeddingsMetadata" - ADD COLUMN "models" VARCHAR(255)[], - DROP COLUMN IF EXISTS "language", - ALTER COLUMN "refId" DROP NOT NULL; - ALTER TABLE "EmbeddingsJobQueue" - ALTER COLUMN "state" TYPE "EmbeddingsStateEnum" USING "state"::text::"EmbeddingsStateEnum", - ADD CONSTRAINT "EmbeddingsJobQueue_objectType_refId_model_key" UNIQUE("objectType", "refId", "model"), - ADD COLUMN "refId" VARCHAR(100), - ADD COLUMN "model" VARCHAR(255), - ADD COLUMN "objectType" "EmbeddingsObjectTypeEnum", - DROP COLUMN "retryAfter", - DROP COLUMN "retryCount", - DROP COLUMN "startAt", - DROP COLUMN "jobData", - DROP COLUMN "priority", - DROP COLUMN "jobType"; - DROP INDEX IF EXISTS "idx_EmbeddingsJobQueue_priority"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1712073121060_removeOneOnOne.ts b/packages/server/postgres/migrations/1712073121060_removeOneOnOne.ts deleted file mode 100644 index c145dc0c8f6..00000000000 --- a/packages/server/postgres/migrations/1712073121060_removeOneOnOne.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`UPDATE "MeetingTemplate" SET "isActive" = false WHERE id = 'oneOnOneAction';`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`UPDATE "MeetingTemplate" SET "isActive" = true WHERE id = 'oneOnOneAction';`) - await client.end() -} diff --git a/packages/server/postgres/migrations/1712074131388_priority.ts b/packages/server/postgres/migrations/1712074131388_priority.ts deleted file mode 100644 index e2f7afd06d9..00000000000 --- a/packages/server/postgres/migrations/1712074131388_priority.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "EmbeddingsJobQueue" - ALTER COLUMN "priority" TYPE INTEGER; - ALTER TABLE "EmbeddingsJobQueue" - ADD COLUMN "model" VARCHAR(255), - ADD COLUMN "embeddingsMetadataId" INTEGER, - ADD CONSTRAINT "fk_embeddingsMetadataId" - FOREIGN KEY("embeddingsMetadataId") - REFERENCES "EmbeddingsMetadata"("id") - ON DELETE SET NULL; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DELETE FROM "EmbeddingsJobQueue"; - ALTER TABLE "EmbeddingsJobQueue" - ALTER COLUMN "priority" TYPE SMALLINT, - DROP COLUMN IF EXISTS "model", - DROP COLUMN IF EXISTS "embeddingsMetadataId"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1712075131388_retroReflectionGroups2.ts b/packages/server/postgres/migrations/1712075131388_retroReflectionGroups2.ts deleted file mode 100644 index 6887169ac6e..00000000000 --- a/packages/server/postgres/migrations/1712075131388_retroReflectionGroups2.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - try { - await r - .table('RetroReflectionGroup') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('RetroReflectionGroup').indexWait().run() - } catch { - // index already exists - } - - await pg.schema - .alterTable('RetroReflectionGroup') - .alterColumn('voterIds', (ac) => ac.setDataType(sql`text[]`)) - .alterColumn('promptId', (ac) => ac.setDataType('varchar(111)')) - .execute() - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'createdAt', - 'updatedAt', - 'isActive', - 'meetingId', - 'promptId', - 'sortOrder', - 'voterIds', - 'smartTitle', - 'title', - 'summary', - 'discussionPromptQuestion' - ] as const - type RetroReflectionGroup = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - const rawRowsToInsert = (await r - .table('RetroReflectionGroup') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as RetroReflectionGroup[] - - const rowsToInsert = rawRowsToInsert.map((row) => ({ - ...row, - title: row.title?.slice(0, 255), - smartTitle: row.smartTitle?.slice(0, 255), - summary: row.summary?.slice(0, 2000) - })) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - try { - await pg - .insertInto('RetroReflectionGroup') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - console.log({lastRow}, rowsToInsert.length) - await Promise.all( - rowsToInsert.map(async (row) => { - try { - const res = await pg - .insertInto('RetroReflectionGroup') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - console.log(e, row) - } - }) - ) - throw e - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('RetroReflectionGroup').indexDrop('updatedAtId').run() - } catch { - // index already dropped - } -} diff --git a/packages/server/postgres/migrations/1714579256634_removeOneOnOneTeam.ts b/packages/server/postgres/migrations/1714579256634_removeOneOnOneTeam.ts deleted file mode 100644 index 8352e12f597..00000000000 --- a/packages/server/postgres/migrations/1714579256634_removeOneOnOneTeam.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - DROP COLUMN IF EXISTS "isOneOnOneTeam"; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "isOneOnOneTeam" BOOLEAN NOT NULL DEFAULT FALSE; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1714598525167_addFavoriteTemplateIds.ts b/packages/server/postgres/migrations/1714598525167_addFavoriteTemplateIds.ts deleted file mode 100644 index 73ac53a6b16..00000000000 --- a/packages/server/postgres/migrations/1714598525167_addFavoriteTemplateIds.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await sql` - ALTER TABLE "User" - ADD COLUMN IF NOT EXISTS "favoriteTemplateIds" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[]; -`.execute(pg) -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await sql` - ALTER TABLE "User" - DROP COLUMN "favoriteTemplateIds"; -`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1716914102795_removeKudos.ts b/packages/server/postgres/migrations/1716914102795_removeKudos.ts deleted file mode 100644 index 291997a9d76..00000000000 --- a/packages/server/postgres/migrations/1716914102795_removeKudos.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema.dropTable('Kudos').ifExists().execute() - try { - await pg.schema - .alterTable('Team') - .dropColumn('giveKudosWithEmoji') - .dropColumn('kudosEmoji') - .execute() - } catch { - // noop - } -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1716995191300_allowGlobalOAuth1Provider.ts b/packages/server/postgres/migrations/1716995191300_allowGlobalOAuth1Provider.ts deleted file mode 100644 index 575c4ad5747..00000000000 --- a/packages/server/postgres/migrations/1716995191300_allowGlobalOAuth1Provider.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - DROP CONSTRAINT IF EXISTS global_provider_must_be_oauth2; - END $$; - `) - await client.end() -} - -export async function down() { - //noop, the constraint was a leftover and served no purpose -} diff --git a/packages/server/postgres/migrations/1717083323369_removeKudosNotifications.ts b/packages/server/postgres/migrations/1717083323369_removeKudosNotifications.ts deleted file mode 100644 index 2607568be0b..00000000000 --- a/packages/server/postgres/migrations/1717083323369_removeKudosNotifications.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - try { - await connectRethinkDB() - await r.table('Notification').filter(r.row('type').eq('KUDOS_RECEIVED')).delete().run() - await r.getPoolMaster()?.drain() - } catch (e) { - console.log(e) - } -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1717096624786_RetroReflection-phase1.ts b/packages/server/postgres/migrations/1717096624786_RetroReflection-phase1.ts deleted file mode 100644 index fbc692e7cac..00000000000 --- a/packages/server/postgres/migrations/1717096624786_RetroReflection-phase1.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'GoogleAnalyzedEntity') THEN - CREATE TYPE "GoogleAnalyzedEntity" AS (name text, salience real, lemma text); - END IF; - - CREATE TABLE IF NOT EXISTS "RetroReflection" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - "meetingId" VARCHAR(100) NOT NULL, - "promptId" VARCHAR(111) NOT NULL, - "sortOrder" DOUBLE PRECISION NOT NULL DEFAULT 0, - "creatorId" VARCHAR(100), - "content" VARCHAR(2000) NOT NULL, - "plaintextContent" VARCHAR(2000) NOT NULL, - "entities" "GoogleAnalyzedEntity"[] NOT NULL DEFAULT array[]::"GoogleAnalyzedEntity"[], - "sentimentScore" REAL, - "reactjis" "Reactji"[] NOT NULL DEFAULT array[]::"Reactji"[], - "reflectionGroupId" VARCHAR(100) NOT NULL, - CONSTRAINT "fk_creatorId" - FOREIGN KEY("creatorId") - REFERENCES "User"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_reflectionGroupId" - FOREIGN KEY("reflectionGroupId") - REFERENCES "RetroReflectionGroup"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_RetroReflection_meetingId" ON "RetroReflection"("meetingId"); - CREATE INDEX IF NOT EXISTS "idx_RetroReflection_promptId" ON "RetroReflection"("promptId"); - CREATE INDEX IF NOT EXISTS "idx_RetroReflection_creatorId" ON "RetroReflection"("creatorId"); - CREATE INDEX IF NOT EXISTS "idx_RetroReflection_reflectionGroupId" ON "RetroReflection"("reflectionGroupId"); - DROP TRIGGER IF EXISTS "update_RetroReflection_updatedAt" ON "RetroReflection"; - CREATE TRIGGER "update_RetroReflection_updatedAt" BEFORE UPDATE ON "RetroReflection" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; - -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "RetroReflection"; - DROP TYPE IF EXISTS "GoogleAnalyzedEntity" CASCADE; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1717685812675_addSuggestedActionTeamIdIndex.ts b/packages/server/postgres/migrations/1717685812675_addSuggestedActionTeamIdIndex.ts deleted file mode 100644 index adbdc0e3534..00000000000 --- a/packages/server/postgres/migrations/1717685812675_addSuggestedActionTeamIdIndex.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r.table('SuggestedAction').indexCreate('teamId').run() - await r.table('SuggestedAction').indexWait().run() - } catch { - // index already exists - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('SuggestedAction').indexDrop('teamId').run() - } catch { - // index already dropped - } -} diff --git a/packages/server/postgres/migrations/1717685812676_addPokerTemplateScaleDimensionScaleIdIndex.ts b/packages/server/postgres/migrations/1717685812676_addPokerTemplateScaleDimensionScaleIdIndex.ts deleted file mode 100644 index 384ec9f1c3f..00000000000 --- a/packages/server/postgres/migrations/1717685812676_addPokerTemplateScaleDimensionScaleIdIndex.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r.table('TemplateDimension').indexCreate('scaleId').run() - await r.table('TemplateDimension').indexWait().run() - } catch { - // index already exists - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('TemplateDimension').indexDrop('scaleId').run() - } catch { - // index already dropped - } -} diff --git a/packages/server/postgres/migrations/1717685812677_addMeetingTemplateEmbedding.ts b/packages/server/postgres/migrations/1717685812677_addMeetingTemplateEmbedding.ts deleted file mode 100644 index f3515f42b1f..00000000000 --- a/packages/server/postgres/migrations/1717685812677_addMeetingTemplateEmbedding.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TYPE "EmbeddingsObjectTypeEnum" ADD VALUE IF NOT EXISTS 'meetingTemplate'; - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - DELETE FROM "EmbeddingsMetadata" WHERE "objectType" = 'meetingTemplate'; - - ALTER TYPE "EmbeddingsObjectTypeEnum" RENAME TO "EmbeddingsObjectTypeEnum_delete"; - - CREATE TYPE "EmbeddingsObjectTypeEnum" AS ENUM ( - 'retrospectiveDiscussionTopic' - ); - - ALTER TABLE "EmbeddingsMetadata" - ALTER COLUMN "objectType" TYPE "EmbeddingsObjectTypeEnum" USING "objectType"::text::"EmbeddingsObjectTypeEnum"; - - DROP TYPE "EmbeddingsObjectTypeEnum_delete"; - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1718014847553_getEmbedderPriority.ts b/packages/server/postgres/migrations/1718014847553_getEmbedderPriority.ts deleted file mode 100644 index 1ea94ecdbad..00000000000 --- a/packages/server/postgres/migrations/1718014847553_getEmbedderPriority.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE OR REPLACE FUNCTION "getEmbedderPriority"(IN "maxDelayInDays" INTEGER) - RETURNS INTEGER LANGUAGE PLPGSQL AS $$ - BEGIN - RETURN -(2 ^ 31) + FLOOR(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) / 1000) + "maxDelayInDays" * 86400; - END - $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP FUNCTION IF EXISTS "getEmbedderPriority"(IN INTEGER); - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1718014858965_updateEmbeddingOnMeetingTemplateUpdate.ts b/packages/server/postgres/migrations/1718014858965_updateEmbeddingOnMeetingTemplateUpdate.ts deleted file mode 100644 index 378f1906ee0..00000000000 --- a/packages/server/postgres/migrations/1718014858965_updateEmbeddingOnMeetingTemplateUpdate.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE OR REPLACE FUNCTION "updateEmbedding"() - RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ - DECLARE - "metadataId" INTEGER; - BEGIN - BEGIN - SELECT id FROM "EmbeddingsMetadata" WHERE "objectType" = 'meetingTemplate' AND "refId" = NEW.id INTO STRICT "metadataId"; - EXCEPTION - WHEN NO_DATA_FOUND THEN - INSERT INTO "EmbeddingsMetadata" ("objectType", "refId", "teamId", "refUpdatedAt") VALUES ('meetingTemplate', NEW.id, NEW."teamId", NEW."updatedAt") RETURNING id INTO "metadataId"; - END; - INSERT INTO "EmbeddingsJobQueue" ("embeddingsMetadataId", "jobType", "priority", "model") VALUES ("metadataId", 'embed:start', "getEmbedderPriority"(1), 'Embeddings_ember_1') ON CONFLICT DO NOTHING; - RETURN NEW; - END - $$; - DROP TRIGGER IF EXISTS "update_embedding_on_MeetingTemplate" ON "MeetingTemplate"; - CREATE TRIGGER "update_embedding_on_MeetingTemplate" AFTER INSERT OR UPDATE ON "MeetingTemplate" FOR EACH ROW EXECUTE PROCEDURE "updateEmbedding"(); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TRIGGER IF EXISTS "update_embedding_on_MeetingTemplate" ON "User"; - DROP FUNCTION IF EXISTS "update_embedding_on_MeetingTemplate"(); - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1718641323037_removeSummaryFromRetroGroup.ts b/packages/server/postgres/migrations/1718641323037_removeSummaryFromRetroGroup.ts deleted file mode 100644 index 7d643fd260e..00000000000 --- a/packages/server/postgres/migrations/1718641323037_removeSummaryFromRetroGroup.ts +++ /dev/null @@ -1,46 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - try { - await connectRethinkDB() - - await r - .table('RetroReflectionGroup') - .replace((row) => row.without('summary')) - .run() - - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema.alterTable('RetroReflectionGroup').dropColumn('summary').execute() - } catch (e) { - console.error('Error during migration:', e) - } -} - -export async function down() { - try { - await connectRethinkDB() - - await r.table('RetroReflectionGroup').update({summary: null}).run() - - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema - .alterTable('RetroReflectionGroup') - .addColumn('summary', 'varchar(2000)') - .execute() - } catch (e) { - console.error('Error during rollback:', e) - } -} diff --git a/packages/server/postgres/migrations/1719162354561_RetroReflection-phase2.ts b/packages/server/postgres/migrations/1719162354561_RetroReflection-phase2.ts deleted file mode 100644 index a8969dc6053..00000000000 --- a/packages/server/postgres/migrations/1719162354561_RetroReflection-phase2.ts +++ /dev/null @@ -1,166 +0,0 @@ -import {ContentState, convertToRaw} from 'draft-js' -import {Kysely, PostgresDialect, sql} from 'kysely' -import extractTextFromDraftString from 'parabol-client/utils/draftjs/extractTextFromDraftString' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -const convertTextToRaw = (text: string) => { - // plaintextContent can have a bunch of linebreaks like \n which get converted into new blocks. - // New blocks take up a BUNCH of space, so we'd rather preserve as much plaintextContent as possible. - const spaceFreeText = text - .split(/\s/) - .filter((s) => s.length) - .join(' ') - const contentState = ContentState.createFromText(spaceFreeText) - const raw = convertToRaw(contentState) - return JSON.stringify(raw) -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - try { - await r - .table('RetroReflection') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('RetroReflection').indexWait().run() - } catch { - // index already exists - } - - const MAX_PG_PARAMS = 65545 - - const PG_COLS = [ - 'id', - 'createdAt', - 'updatedAt', - 'isActive', - 'meetingId', - 'promptId', - 'sortOrder', - 'creatorId', - 'content', - 'plaintextContent', - 'entities', - 'sentimentScore', - 'reactjis', - 'reflectionGroupId' - ] as const - type RetroReflection = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - const capContent = (content: string, plaintextContent: string) => { - let nextPlaintextContent = plaintextContent || extractTextFromDraftString(content) - // if they got out of hand with formatting, extract the text & convert it back - let nextContent = content.length <= 2000 ? content : convertTextToRaw(nextPlaintextContent) - while (nextContent.length > 2000 || nextPlaintextContent.length > 2000) { - const maxLen = Math.max(nextContent.length, nextPlaintextContent.length) - const overage = maxLen - 2000 - const stopIdx = nextPlaintextContent.length - overage - 1 - nextPlaintextContent = nextPlaintextContent.slice(0, stopIdx) - nextContent = convertTextToRaw(nextPlaintextContent) - } - return {content: nextContent, plaintextContent: nextPlaintextContent} - } - - let curUpdatedAt = r.minval - let curId = r.minval - - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curUpdatedAt, curId) - const rawRowsToInsert = (await r - .table('RetroReflection') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as RetroReflection[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const nonzeroEntities = row.entities?.length > 0 ? row.entities : undefined - const normalizedEntities = nonzeroEntities?.map((e: any) => ({ - ...e, - salience: typeof e.salience === 'number' ? e.salience : 0 - })) - return { - ...row, - ...capContent(row.content, row.plaintextContent), - reactjis: row.reactjis?.map((r: any) => `(${r.id},${r.userId})`), - entities: normalizedEntities - ? sql`(select array_agg((name, salience, lemma)::"GoogleAnalyzedEntity") from json_populate_recordset(null::"GoogleAnalyzedEntity", ${JSON.stringify(normalizedEntities)}))` - : undefined - } - }) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - let isFailure = false - // NOTE: This migration inserts row-by-row because there are so many referential integrity errors - // Do not copy this migration logic for future migrations, it is slow! - const insertSingleRow = async (row: RetroReflection) => { - if (isFailure) return - try { - await pg - .insertInto('RetroReflection') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_reflectionGroupId') { - await pg - .insertInto('RetroReflectionGroup') - .values({ - id: row.reflectionGroupId, - createdAt: row.createdAt, - updatedAt: row.updatedAt, - isActive: row.isActive, - meetingId: row.meetingId, - promptId: row.promptId - }) - // multiple reflections may be trying to create the same group - .onConflict((oc) => oc.doNothing()) - .execute() - await insertSingleRow(row) - } else if (e.constraint === 'fk_creatorId') { - await r.table('RetroReflection').get(row.id).update({creatorId: null}).run() - await insertSingleRow({...row, creatorId: null}) - } else { - isFailure = true - console.log(e, row) - } - } - } - await Promise.all(rowsToInsert.map(insertSingleRow)) - if (isFailure) { - throw 'Failed batch' - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('RetroReflection').indexDrop('updatedAtId').run() - } catch { - // index already dropped - } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.deleteFrom('RetroReflection').execute() -} diff --git a/packages/server/postgres/migrations/1719262354561_reactji-rename.ts b/packages/server/postgres/migrations/1719262354561_reactji-rename.ts deleted file mode 100644 index 21461808e6e..00000000000 --- a/packages/server/postgres/migrations/1719262354561_reactji-rename.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - - await client.query(` - ALTER TYPE "Reactji" RENAME ATTRIBUTE "userid" to "userId"; - ALTER TYPE "Reactji" RENAME ATTRIBUTE "shortname" to "id"; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(`` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1719348524673_TimelineEvent-phase1.ts b/packages/server/postgres/migrations/1719348524673_TimelineEvent-phase1.ts deleted file mode 100644 index b5c9a458bc0..00000000000 --- a/packages/server/postgres/migrations/1719348524673_TimelineEvent-phase1.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - // teamId, orgId, meetingId - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TimelineEventEnum') THEN - CREATE TYPE "TimelineEventEnum" AS ENUM ( - 'TEAM_PROMPT_COMPLETE', - 'POKER_COMPLETE', - 'actionComplete', - 'createdTeam', - 'joinedParabol', - 'retroComplete' - ); - END IF; - - CREATE TABLE IF NOT EXISTS "TimelineEvent" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "interactionCount" SMALLINT NOT NULL DEFAULT 0, - "seenCount" SMALLINT NOT NULL DEFAULT 0, - "type" "TimelineEventEnum" NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100), - "orgId" VARCHAR(100), - "meetingId" VARCHAR(100), - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TimelineEvent_userId_createdAt" ON "TimelineEvent"("userId", "createdAt") WHERE "isActive" = TRUE; - CREATE INDEX IF NOT EXISTS "idx_TimelineEvent_meetingId" ON "TimelineEvent"("meetingId"); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "TimelineEvent"; - DROP TYPE "TimelineEventEnum"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1719351990570_TimelineEvent-phase2.ts b/packages/server/postgres/migrations/1719351990570_TimelineEvent-phase2.ts deleted file mode 100644 index 5f70015a119..00000000000 --- a/packages/server/postgres/migrations/1719351990570_TimelineEvent-phase2.ts +++ /dev/null @@ -1,103 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - try { - console.log('Adding index') - await r - .table('TimelineEvent') - .indexCreate('createdAtId', (row: any) => [row('createdAt'), row('id')]) - .run() - await r.table('TimelineEvent').indexWait().run() - } catch { - // index already exists - } - console.log('Adding index complete') - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'createdAt', - 'interactionCount', - 'seenCount', - 'type', - 'userId', - 'teamId', - 'orgId', - 'meetingId', - 'isActive' - ] as const - type TimelineEvent = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curUpdatedAt, curId) - const rowsToInsert = (await r - .table('TimelineEvent') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'createdAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'createdAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as TimelineEvent[] - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.createdAt - curId = lastRow.id - try { - await pg - .insertInto('TimelineEvent') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - await Promise.all( - rowsToInsert.map(async (row) => { - try { - const res = await pg - .insertInto('TimelineEvent') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_userId' || e.constraint === 'fk_teamId') { - // console.log(`Skipping ${row.id} because it has no user/team`) - return - } - console.log(e, row) - } - }) - ) - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('TimelineEvent').indexDrop('createdAtId').run() - } catch { - // index already dropped - } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.deleteFrom('TimelineEvent').execute() -} diff --git a/packages/server/postgres/migrations/1719435764047_Organization-phase1.ts b/packages/server/postgres/migrations/1719435764047_Organization-phase1.ts deleted file mode 100644 index 719d7a6953b..00000000000 --- a/packages/server/postgres/migrations/1719435764047_Organization-phase1.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - //activeDomain has a few that are longer than 100 - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'CreditCard') THEN - CREATE TYPE "CreditCard" AS (brand text, expiry text, last4 smallint); - END IF; - - CREATE TABLE IF NOT EXISTS "Organization" ( - "id" VARCHAR(100) PRIMARY KEY, - "activeDomain" VARCHAR(100), - "isActiveDomainTouched" BOOLEAN NOT NULL DEFAULT FALSE, - "creditCard" "CreditCard", - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "name" VARCHAR(100) NOT NULL, - "payLaterClickCount" SMALLINT NOT NULL DEFAULT 0, - "periodEnd" TIMESTAMP WITH TIME ZONE, - "periodStart" TIMESTAMP WITH TIME ZONE, - "picture" VARCHAR(2056), - "showConversionModal" BOOLEAN NOT NULL DEFAULT FALSE, - "stripeId" VARCHAR(100), - "stripeSubscriptionId" VARCHAR(100), - "upcomingInvoiceEmailSentAt" TIMESTAMP WITH TIME ZONE, - "tier" "TierEnum" NOT NULL DEFAULT 'starter', - "tierLimitExceededAt" TIMESTAMP WITH TIME ZONE, - "trialStartDate" TIMESTAMP WITH TIME ZONE, - "scheduledLockAt" TIMESTAMP WITH TIME ZONE, - "lockedAt" TIMESTAMP WITH TIME ZONE, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "featureFlags" TEXT[] NOT NULL DEFAULT '{}' - ); - CREATE INDEX IF NOT EXISTS "idx_Organization_activeDomain" ON "Organization"("activeDomain"); - CREATE INDEX IF NOT EXISTS "idx_Organization_tier" ON "Organization"("tier"); - DROP TRIGGER IF EXISTS "update_Organization_updatedAt" ON "Organization"; - CREATE TRIGGER "update_Organization_updatedAt" BEFORE UPDATE ON "Organization" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "Organization"; - DROP TYPE "CreditCard"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1720026588542_Organization-phase2.ts b/packages/server/postgres/migrations/1720026588542_Organization-phase2.ts deleted file mode 100644 index 78776890b41..00000000000 --- a/packages/server/postgres/migrations/1720026588542_Organization-phase2.ts +++ /dev/null @@ -1,121 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -const toCreditCard = (creditCard: any) => { - if (!creditCard) return null - return sql`(select json_populate_record(null::"CreditCard", ${JSON.stringify(creditCard)}))` -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - try { - console.log('Adding index') - await r - .table('Organization') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('Organization').indexWait().run() - } catch { - // index already exists - } - console.log('Adding index complete') - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'activeDomain', - 'isActiveDomainTouched', - 'creditCard', - 'createdAt', - 'name', - 'payLaterClickCount', - 'periodEnd', - 'periodStart', - 'picture', - 'showConversionModal', - 'stripeId', - 'stripeSubscriptionId', - 'upcomingInvoiceEmailSentAt', - 'tier', - 'tierLimitExceededAt', - 'trialStartDate', - 'scheduledLockAt', - 'lockedAt', - 'updatedAt', - 'featureFlags' - ] as const - type Organization = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curUpdatedAt, curId) - const rawRowsToInsert = (await r - .table('Organization') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as Organization[] - - const rowsToInsert = rawRowsToInsert.map((row) => ({ - ...row, - activeDomain: row.activeDomain?.slice(0, 100) ?? null, - name: row.name.slice(0, 100), - creditCard: toCreditCard(row.creditCard) - })) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - try { - await pg - .insertInto('Organization') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('Organization') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - console.log(e, row) - } - }) - ) - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('Organization').indexDrop('updatedAtId').run() - } catch { - // index already dropped - } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.deleteFrom('Organization').execute() -} diff --git a/packages/server/postgres/migrations/1720517256158_TimelineEvent-phase4.ts b/packages/server/postgres/migrations/1720517256158_TimelineEvent-phase4.ts deleted file mode 100644 index a63a8c23ca1..00000000000 --- a/packages/server/postgres/migrations/1720517256158_TimelineEvent-phase4.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r.tableDrop('TimelineEvent').run() - } catch (error) { - // table already dropped - } -} - -export async function down() { - // No migration down -} diff --git a/packages/server/postgres/migrations/1720517631974_RetroReflectionGroup-phase4.ts b/packages/server/postgres/migrations/1720517631974_RetroReflectionGroup-phase4.ts deleted file mode 100644 index 20b56b3c712..00000000000 --- a/packages/server/postgres/migrations/1720517631974_RetroReflectionGroup-phase4.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r.tableDrop('RetroReflectionGroup').run() - } catch (error) { - // table already dropped - } -} - -export async function down() { - // No migration down -} diff --git a/packages/server/postgres/migrations/1720518455750_RetroReflection-phase4.ts b/packages/server/postgres/migrations/1720518455750_RetroReflection-phase4.ts deleted file mode 100644 index 120661226c6..00000000000 --- a/packages/server/postgres/migrations/1720518455750_RetroReflection-phase4.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - try { - await r.tableDrop('RetroReflection').run() - } catch (error) { - // table already dropped - } -} - -export async function down() { - // No migration down -} diff --git a/packages/server/postgres/migrations/1720556055134_OrganizationUser-phase1.ts b/packages/server/postgres/migrations/1720556055134_OrganizationUser-phase1.ts deleted file mode 100644 index 0d348909bff..00000000000 --- a/packages/server/postgres/migrations/1720556055134_OrganizationUser-phase1.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'OrgUserRoleEnum') THEN - CREATE TYPE "OrgUserRoleEnum" AS ENUM ( - 'BILLING_LEADER', - 'ORG_ADMIN' - ); - END IF; - CREATE TABLE IF NOT EXISTS "OrganizationUser" ( - "id" VARCHAR(100) PRIMARY KEY, - "suggestedTier" "TierEnum", - "inactive" BOOLEAN NOT NULL DEFAULT FALSE, - "joinedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "orgId" VARCHAR(100) NOT NULL, - "removedAt" TIMESTAMP WITH TIME ZONE, - "role" "OrgUserRoleEnum", - "userId" VARCHAR(100) NOT NULL, - "tier" "TierEnum" NOT NULL, - "trialStartDate" TIMESTAMP WITH TIME ZONE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_orgId" - FOREIGN KEY("orgId") - REFERENCES "Organization"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_OrganizationUser_tier" ON "OrganizationUser"("tier") WHERE "removedAt" IS NULL AND "inactive" = FALSE; - CREATE INDEX IF NOT EXISTS "idx_OrganizationUser_orgId" ON "OrganizationUser"("orgId") WHERE "removedAt" IS NULL; - CREATE INDEX IF NOT EXISTS "idx_OrganizationUser_userId" ON "OrganizationUser"("userId") WHERE "removedAt" IS NULL; - - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "OrganizationUser"; - DROP TYPE "OrgUserRoleEnum"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1720640784862_OrganizationUser-phase2.ts b/packages/server/postgres/migrations/1720640784862_OrganizationUser-phase2.ts deleted file mode 100644 index ddeb041d9fc..00000000000 --- a/packages/server/postgres/migrations/1720640784862_OrganizationUser-phase2.ts +++ /dev/null @@ -1,110 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - try { - console.log('Adding index') - await r - .table('OrganizationUser') - .indexCreate('joinedAtId', (row: any) => [row('joinedAt'), row('id')]) - .run() - await r.table('OrganizationUser').indexWait().run() - } catch { - // index already exists - } - await r.table('OrganizationUser').get('aGhostOrganizationUser').update({tier: 'enterprise'}).run() - await console.log('Adding index complete') - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'suggestedTier', - 'inactive', - 'joinedAt', - 'orgId', - 'removedAt', - 'role', - 'userId', - 'tier', - 'trialStartDate' - ] as const - type OrganizationUser = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curjoinedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curjoinedAt, curId) - const rawRowsToInsert = (await r - .table('OrganizationUser') - .between([curjoinedAt, curId], [r.maxval, r.maxval], { - index: 'joinedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'joinedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as OrganizationUser[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const {newUserUntil, ...rest} = row as any - return { - ...rest - } - }) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curjoinedAt = lastRow.joinedAt - curId = lastRow.id - try { - await pg - .insertInto('OrganizationUser') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('OrganizationUser') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_userId' || e.constraint === 'fk_orgId') { - console.log(`Skipping ${row.id} because it has no user/org`) - return - } - console.log(e, row) - } - }) - ) - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('OrganizationUser').indexDrop('joinedAtId').run() - } catch { - // index already dropped - } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.deleteFrom('OrganizationUser').execute() -} diff --git a/packages/server/postgres/migrations/1720689742934_fixThreatLevelPromptColors.ts b/packages/server/postgres/migrations/1720689742934_fixThreatLevelPromptColors.ts deleted file mode 100644 index 72cd4145d7c..00000000000 --- a/packages/server/postgres/migrations/1720689742934_fixThreatLevelPromptColors.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - - await r - .table('ReflectPrompt') - .get('threatLevelPremortemTemplateSeverePrompt') - .update({groupColor: '#FD6157'}) - .run() - await r - .table('ReflectPrompt') - .get('threatLevelPremortemTemplateElevatedPrompt') - .update({groupColor: '#FFCC63'}) - .run() - await r - .table('ReflectPrompt') - .get('threatLevelPremortemTemplateLowPrompt') - .update({groupColor: '#66BC8C'}) - .run() -} - -export async function down() { - await connectRethinkDB() - - await r - .table('ReflectPrompt') - .get('threatLevelPremortemTemplateSeverePrompt') - .update({groupColor: '#66BC8C'}) - .run() - await r - .table('ReflectPrompt') - .get('threatLevelPremortemTemplateElevatedPrompt') - .update({groupColor: '#FD6157'}) - .run() - await r - .table('ReflectPrompt') - .get('threatLevelPremortemTemplateLowPrompt') - .update({groupColor: '#FFCC63'}) - .run() -} diff --git a/packages/server/postgres/migrations/1720730818119_TeamMember-phase1.ts b/packages/server/postgres/migrations/1720730818119_TeamMember-phase1.ts deleted file mode 100644 index c1008de261d..00000000000 --- a/packages/server/postgres/migrations/1720730818119_TeamMember-phase1.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TeamDrawerEnum') THEN - CREATE TYPE "TeamDrawerEnum" AS ENUM ( - 'agenda', - 'manageTeam' - ); - END IF; - CREATE TABLE IF NOT EXISTS "TeamMember" ( - "id" VARCHAR(100) PRIMARY KEY, - "isNotRemoved" BOOLEAN NOT NULL DEFAULT TRUE, - "isLead" BOOLEAN NOT NULL DEFAULT FALSE, - "isSpectatingPoker" BOOLEAN NOT NULL DEFAULT FALSE, - "email" "citext" NOT NULL, - "openDrawer" "TeamDrawerEnum", - "picture" VARCHAR(2056) NOT NULL, - "preferredName" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TeamMember_teamId" ON "TeamMember"("teamId") WHERE "isNotRemoved" = TRUE; - CREATE INDEX IF NOT EXISTS "idx_TeamMember_userId" ON "TeamMember"("userId") WHERE "isNotRemoved" = TRUE; - DROP TRIGGER IF EXISTS "update_TeamMember_updatedAt" ON "TeamMember"; - CREATE TRIGGER "update_TeamMember_updatedAt" BEFORE UPDATE ON "TeamMember" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "TeamMember"; - DROP TYPE "TeamDrawerEnum"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1721348544381_QueryMapOneShot.ts b/packages/server/postgres/migrations/1721348544381_QueryMapOneShot.ts deleted file mode 100644 index d34461815b4..00000000000 --- a/packages/server/postgres/migrations/1721348544381_QueryMapOneShot.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - CREATE TABLE IF NOT EXISTS "QueryMap" ( - "id" VARCHAR(24) PRIMARY KEY, - "query" TEXT NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() - ) -`.execute(pg) - const queries = await r - .table('QueryMap') - .filter((row) => row('createdAt').default(null).ne(null)) - .run() - if (queries.length === 0) return - await pg.insertInto('QueryMap').values(queries).execute() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "QueryMap"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1721356124871_TeamMember-phase2.ts b/packages/server/postgres/migrations/1721356124871_TeamMember-phase2.ts deleted file mode 100644 index f88c3c6a97d..00000000000 --- a/packages/server/postgres/migrations/1721356124871_TeamMember-phase2.ts +++ /dev/null @@ -1,144 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - // add a dummy date for nulls - const parabolEpoch = new Date('2016-06-01') - await r - .table('TeamMember') - .update((row) => ({ - updatedAt: row('updatedAt').default(parabolEpoch), - createdAt: row('createdAt').default(parabolEpoch) - })) - .run() - const strDates = await r - .table('TeamMember') - .filter((row) => row('updatedAt').typeOf().eq('STRING')) - .pluck('updatedAt', 'id', 'createdAt') - .run() - const dateDates = strDates.map((d) => ({ - id: d.id, - updatedAt: new Date(d.updatedAt), - createdAt: new Date(d.createdAt) - })) - // some dates are - await r(dateDates) - .forEach((row: any) => { - return r - .table('TeamMember') - .get(row('id')) - .update({updatedAt: row('updatedAt')}) - }) - .run() - - try { - console.log('Adding index') - await r - .table('TeamMember') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('TeamMember').indexWait().run() - } catch { - // index already exists - } - - await console.log('Adding index complete') - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'isNotRemoved', - 'isLead', - 'isSpectatingPoker', - 'email', - 'openDrawer', - 'picture', - 'preferredName', - 'teamId', - 'userId', - 'createdAt', - 'updatedAt' - ] as const - type TeamMember = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('TeamMember') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as TeamMember[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const {preferredName, picture, ...rest} = row as any - return { - ...rest, - preferredName: preferredName.slice(0, 100), - picture: picture.slice(0, 2056) - } - }) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - try { - await pg - .insertInto('TeamMember') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('TeamMember') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_userId' || e.constraint === 'fk_teamId') { - console.log(`Skipping ${row.id} because it has no user/team`) - return - } - console.log(e, row) - } - }) - ) - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('TeamMember').indexDrop('updatedAtId').run() - } catch { - // index already dropped - } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.deleteFrom('TeamMember').execute() -} diff --git a/packages/server/postgres/migrations/1721405703862_TemplateScale.ts b/packages/server/postgres/migrations/1721405703862_TemplateScale.ts deleted file mode 100644 index 7926e454beb..00000000000 --- a/packages/server/postgres/migrations/1721405703862_TemplateScale.ts +++ /dev/null @@ -1,149 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -const START_CHAR_CODE = 32 -const END_CHAR_CODE = 126 - -export function positionAfter(pos: string) { - for (let i = pos.length - 1; i >= 0; i--) { - const curCharCode = pos.charCodeAt(i) - if (curCharCode < END_CHAR_CODE) { - return pos.substr(0, i) + String.fromCharCode(curCharCode + 1) - } - } - return pos + String.fromCharCode(START_CHAR_CODE + 1) -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "TemplateScale" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "name" VARCHAR(50) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "parentScaleId" VARCHAR(100), - "isStarter" BOOLEAN NOT NULL DEFAULT FALSE, - "removedAt" TIMESTAMP WITH TIME ZONE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TemplateScale_teamId" ON "TemplateScale"("teamId") WHERE "removedAt" IS NULL; - DROP TRIGGER IF EXISTS "update_TemplateScale_updatedAt" ON "TemplateScale"; - CREATE TRIGGER "update_TemplateScale_updatedAt" BEFORE UPDATE ON "TemplateScale" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - CREATE TABLE IF NOT EXISTS "TemplateScaleValue" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "templateScaleId" VARCHAR(100) NOT NULL, - "sortOrder" VARCHAR(64) NOT NULL COLLATE "C", - "color" VARCHAR(9) NOT NULL, - "label" VARCHAR(18) NOT NULL, - UNIQUE ("templateScaleId","label"), - CONSTRAINT "fk_templateScaleId" - FOREIGN KEY("templateScaleId") - REFERENCES "TemplateScale"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TemplateScaleValue_templateScaleId" ON "TemplateScaleValue"("templateScaleId"); - CREATE OR REPLACE FUNCTION "set_TemplateScale_updatedAt"() - RETURNS TRIGGER AS $t$ - BEGIN - -- Update the updatedAt column in TemplateScale - UPDATE "TemplateScale" - SET "updatedAt" = CURRENT_TIMESTAMP - WHERE id = NEW."templateScaleId"; - RETURN NEW; - END; - $t$ LANGUAGE plpgsql; - CREATE TRIGGER "update_TemplateScale_updatedAt_from_TemplateScaleValue" - AFTER INSERT OR UPDATE OR DELETE ON "TemplateScaleValue" - FOR EACH ROW - EXECUTE FUNCTION "set_TemplateScale_updatedAt"(); - END $$; -`.execute(pg) - - const rTemplateScales = await r.table('TemplateScale').coerceTo('array').run() - const templateScaleValues = [] as { - templateScaleId: string - sortOrder: string - color: string - label: string - }[] - const templateScales = rTemplateScales.map((templateScale) => { - const {id, createdAt, name, teamId, updatedAt, parentScaleId, isStarter, removedAt, values} = - templateScale - let curSortOrder = '' - const templateVals = values?.map((value) => { - const sortOrder = positionAfter(curSortOrder) - curSortOrder = sortOrder - return { - templateScaleId: id, - sortOrder, - color: value.color, - label: value.label.slice(0, 8) - } - }) - templateScaleValues.push(...templateVals) - return {id, createdAt, name, teamId, updatedAt, parentScaleId, isStarter, removedAt} - }) - - const chunk = (arr: any[], size: number) => - Array.from({length: Math.ceil(arr.length / size)}, (_, i) => - arr.slice(i * size, i * size + size) - ) - - const valueChunks = chunk(templateScaleValues, 10000) - - await pg.insertInto('TemplateScale').values(templateScales).execute() - await Promise.all( - valueChunks.map(async (chunk) => { - try { - return await pg.insertInto('TemplateScaleValue').values(chunk).execute() - } catch (e) { - await Promise.all( - chunk.map(async (row) => { - try { - await pg - .insertInto('TemplateScaleValue') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - console.log(e, row) - } - }) - ) - } - }) - ) - - await pg.schema - .alterTable('TemplateScale') - .addForeignKeyConstraint('fk_parentScaleId', ['parentScaleId'], 'TemplateScale', ['id']) - .onDelete('set null') - .execute() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "TemplateScaleValue"; - DROP TABLE IF EXISTS "TemplateScale"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1721858364099_TemplateDimension.ts b/packages/server/postgres/migrations/1721858364099_TemplateDimension.ts deleted file mode 100644 index 7b118043775..00000000000 --- a/packages/server/postgres/migrations/1721858364099_TemplateDimension.ts +++ /dev/null @@ -1,143 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const START_CHAR_CODE = 32 - const END_CHAR_CODE = 126 - - function positionAfter(pos: string) { - for (let i = pos.length - 1; i >= 0; i--) { - const curCharCode = pos.charCodeAt(i) - if (curCharCode < END_CHAR_CODE) { - return pos.substr(0, i) + String.fromCharCode(curCharCode + 1) - } - } - return pos + String.fromCharCode(START_CHAR_CODE + 1) - } - - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "TemplateDimension" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "name" VARCHAR(50) NOT NULL, - "description" VARCHAR(256) NOT NULL DEFAULT '', - "teamId" VARCHAR(100) NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "templateId" VARCHAR(100) NOT NULL, - "scaleId" VARCHAR(100) NOT NULL, - "sortOrder" VARCHAR(64) NOT NULL COLLATE "C", - "removedAt" TIMESTAMP WITH TIME ZONE, - UNIQUE ("teamId","name","removedAt"), - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_templateId" - FOREIGN KEY("templateId") - REFERENCES "MeetingTemplate"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_scaleId" - FOREIGN KEY("scaleId") - REFERENCES "TemplateScale"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TemplateDimension_teamId" ON "TemplateDimension"("teamId") WHERE "removedAt" IS NULL; - CREATE INDEX IF NOT EXISTS "idx_TemplateDimension_scaleId" ON "TemplateDimension"("scaleId") WHERE "removedAt" IS NULL; - CREATE INDEX IF NOT EXISTS "idx_TemplateDimension_templateId" ON "TemplateDimension"("templateId") WHERE "removedAt" IS NULL; - DROP TRIGGER IF EXISTS "update_TemplateDimension_updatedAt" ON "TemplateDimension"; - CREATE TRIGGER "update_TemplateDimension_updatedAt" BEFORE UPDATE ON "TemplateDimension" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - CREATE OR REPLACE FUNCTION "set_TemplateDimension_updatedAt"() - RETURNS TRIGGER AS $t$ - BEGIN - -- Update the updatedAt column in TemplateDimension - UPDATE "TemplateDimension" - SET "updatedAt" = CURRENT_TIMESTAMP - WHERE "scaleId" = NEW."id"; - RETURN NEW; - END; - $t$ LANGUAGE plpgsql; - CREATE OR REPLACE TRIGGER "update_TemplateDimension_updatedAt_from_TemplateScale" - AFTER INSERT OR UPDATE OR DELETE ON "TemplateScale" - FOR EACH ROW - EXECUTE FUNCTION "set_TemplateDimension_updatedAt"(); - - CREATE OR REPLACE FUNCTION "set_MeetingTemplate_updatedAt"() - RETURNS TRIGGER AS $t$ - BEGIN - -- Update the updatedAt column in MeetingTemplate - UPDATE "MeetingTemplate" - SET "updatedAt" = CURRENT_TIMESTAMP - WHERE "id" = NEW."templateId"; - RETURN NEW; - END; - $t$ LANGUAGE plpgsql; - CREATE OR REPLACE TRIGGER "update_MeetingTemplate_updatedAt_from_TemplateDimension" - AFTER INSERT OR UPDATE OR DELETE ON "TemplateDimension" - FOR EACH ROW - EXECUTE FUNCTION "set_MeetingTemplate_updatedAt"(); - END $$; -`.execute(pg) - - const rDimensions = await r - .table('TemplateDimension') - .orderBy('sortOrder') - .coerceTo('array') - .run() - const chunk = (arr: any[], size: number) => - Array.from({length: Math.ceil(arr.length / size)}, (_, i) => - arr.slice(i * size, i * size + size) - ) - const curSortOrder = positionAfter('') - const dimensions = rDimensions.map((dimension) => { - const sortOrder = positionAfter(curSortOrder) - return { - ...dimension, - sortOrder, - description: dimension.description || '' - } - }) - const chunks = chunk(dimensions, 5000) - - await Promise.all( - chunks.map(async (chunk) => { - try { - return await pg.insertInto('TemplateDimension').values(chunk).execute() - } catch (e) { - await Promise.all( - chunk.map(async (row) => { - try { - await pg - .insertInto('TemplateDimension') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - console.log(e, row) - } - }) - ) - } - }) - ) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "TemplateDimension"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1721868364099_addEmailVerification.ts b/packages/server/postgres/migrations/1721868364099_addEmailVerification.ts deleted file mode 100644 index b725ec8f65f..00000000000 --- a/packages/server/postgres/migrations/1721868364099_addEmailVerification.ts +++ /dev/null @@ -1,53 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - CREATE TABLE "EmailVerification" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "email" "citext" NOT NULL, - "expiration" TIMESTAMP WITH TIME ZONE NOT NULL, - "token" VARCHAR(100) NOT NULL, - "hashedPassword" VARCHAR(100), - "invitationToken" VARCHAR(100), - "pseudoId" VARCHAR(100) - ); - - CREATE INDEX IF NOT EXISTS "idx_EmailVerification_email" ON "EmailVerification"("email"); - CREATE INDEX IF NOT EXISTS "idx_EmailVerification_token" ON "EmailVerification"("token"); - `.execute(pg) - - const rData = await r.table('EmailVerification').coerceTo('array').run() - const insertData = rData.map((row) => { - const {email, expiration, hashedPassword, token, invitationToken, pseudoId} = row - return { - email, - expiration, - hashedPassword, - token, - invitationToken, - pseudoId - } - }) - if (insertData.length === 0) return - await pg.insertInto('EmailVerification').values(insertData).execute() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "EmailVerification"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1721940319404_SuggestedAction-phase1.ts b/packages/server/postgres/migrations/1721940319404_SuggestedAction-phase1.ts deleted file mode 100644 index 61f99780e50..00000000000 --- a/packages/server/postgres/migrations/1721940319404_SuggestedAction-phase1.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'SuggestedActionTypeEnum') THEN - CREATE TYPE "SuggestedActionTypeEnum" AS ENUM ( - 'inviteYourTeam', - 'tryTheDemo', - 'createNewTeam', - 'tryRetroMeeting', - 'tryActionMeeting' - ); - END IF; - CREATE TABLE IF NOT EXISTS "SuggestedAction" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "priority" SMALLINT NOT NULL DEFAULT 0, - "removedAt" TIMESTAMP WITH TIME ZONE, - "type" "SuggestedActionTypeEnum" NOT NULL, - "teamId" VARCHAR(100), - "userId" VARCHAR(100) NOT NULL, - UNIQUE("userId", "type"), - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_SuggestedAction_teamId" ON "SuggestedAction"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_SuggestedAction_userId" ON "SuggestedAction"("userId"); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "SuggestedAction"; - DROP TYPE "SuggestedActionTypeEnum"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1722526485990_orgIdForIntegrationProvider.ts b/packages/server/postgres/migrations/1722526485990_orgIdForIntegrationProvider.ts deleted file mode 100644 index 80c1a8b1381..00000000000 --- a/packages/server/postgres/migrations/1722526485990_orgIdForIntegrationProvider.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - ADD COLUMN IF NOT EXISTS "orgId" VARCHAR(100), - ALTER COLUMN "teamId" DROP NOT NULL, - DROP CONSTRAINT "IntegrationProvider_teamId_service_authStrategy_key"; - UPDATE "IntegrationProvider" - SET - "orgId" = (SELECT "orgId" FROM "Team" WHERE "id" = "teamId"), - "teamId" = NULL - WHERE "scope" = 'org'; - UPDATE "IntegrationProvider" - SET - "teamId" = NULL - WHERE "scope" = 'global'; - ALTER TABLE "IntegrationProvider" - ADD CONSTRAINT "unique_per_team_and_org" UNIQUE ("orgId", "teamId", "service", "authStrategy"), - ADD CONSTRAINT "scope_org_has_only_orgId" CHECK - ("scope" <> 'org' OR ("orgId" IS NOT NULL AND "teamId" IS NULL)), - ADD CONSTRAINT "scope_team_has_only_teamId" CHECK - ("scope" <> 'team' OR ("teamId" IS NOT NULL AND "orgId" IS NULL)), - ADD CONSTRAINT "scope_global_has_neither_teamId_orgId" CHECK - ("scope" <> 'global' OR ("orgId" IS NULL AND "teamId" IS NULL)); - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - DROP CONSTRAINT "scope_org_has_only_orgId", - DROP CONSTRAINT "scope_team_has_only_teamId", - DROP CONSTRAINT "scope_global_has_neither_teamId_orgId"; - UPDATE "IntegrationProvider" AS "ip" - SET - "teamId" = (SELECT "id" FROM "Team" AS "t" WHERE "t"."orgId" = "ip"."orgId" LIMIT 1) - WHERE "scope" = 'org'; - UPDATE "IntegrationProvider" - SET - "teamId" = 'aGhostTeam' - WHERE "scope" = 'global'; - ALTER TABLE "IntegrationProvider" - DROP CONSTRAINT "unique_per_team_and_org", - DROP COLUMN "orgId", - ALTER COLUMN "teamId" SET NOT NULL, - ADD CONSTRAINT "IntegrationProvider_teamId_service_authStrategy_key" UNIQUE ("teamId", "service", "authStrategy"); - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1722632147643_IntegrationProvider-null-not-distinct.ts b/packages/server/postgres/migrations/1722632147643_IntegrationProvider-null-not-distinct.ts deleted file mode 100644 index bdcc8bae454..00000000000 --- a/packages/server/postgres/migrations/1722632147643_IntegrationProvider-null-not-distinct.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - DROP CONSTRAINT "unique_per_team_and_org"; - ALTER TABLE "IntegrationProvider" - ADD CONSTRAINT "unique_per_team_and_org" UNIQUE NULLS NOT DISTINCT ("orgId", "teamId", "service", "authStrategy"); - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "IntegrationProvider" - DROP CONSTRAINT "unique_per_team_and_org"; - ALTER TABLE "IntegrationProvider" - ADD CONSTRAINT "unique_per_team_and_org" UNIQUE ("orgId", "teamId", "service", "authStrategy"); - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1722637208553_SuggestAction-phase2.ts b/packages/server/postgres/migrations/1722637208553_SuggestAction-phase2.ts deleted file mode 100644 index 7414c33de7e..00000000000 --- a/packages/server/postgres/migrations/1722637208553_SuggestAction-phase2.ts +++ /dev/null @@ -1,100 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -const toCreditCard = (creditCard: any) => { - if (!creditCard) return null - return sql`(select json_populate_record(null::"CreditCard", ${JSON.stringify(creditCard)}))` -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - try { - console.log('Adding index') - await r - .table('SuggestedAction') - .indexCreate('createdAtId', (row: any) => [row('createdAt'), row('id')]) - .run() - await r.table('SuggestedAction').indexWait().run() - } catch { - // index already exists - } - console.log('Adding index complete') - const MAX_PG_PARAMS = 65545 - const PG_COLS = ['id', 'createdAt', 'priority', 'removedAt', 'type', 'teamId', 'userId'] as const - type SuggestedAction = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curcreatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curcreatedAt, curId) - const rawRowsToInsert = (await r - .table('SuggestedAction') - .between([curcreatedAt, curId], [r.maxval, r.maxval], { - index: 'createdAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'createdAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as SuggestedAction[] - - const rowsToInsert = rawRowsToInsert.map((row) => ({ - ...row - })) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curcreatedAt = lastRow.createdAt - curId = lastRow.id - try { - await pg - .insertInto('SuggestedAction') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('SuggestedAction') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_userId' || e.constraint === 'fk_teamId') { - console.log(`Skipping ${row.id} because it has no user/team`) - return - } - console.log(e, row) - } - }) - ) - } - } -} - -export async function down() { - await connectRethinkDB() - try { - await r.table('SuggestedAction').indexDrop('createdAtId').run() - } catch { - // index already dropped - } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "SuggestedAction" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1722638208553_addInsight.ts b/packages/server/postgres/migrations/1722638208553_addInsight.ts deleted file mode 100644 index d696b2fdd60..00000000000 --- a/packages/server/postgres/migrations/1722638208553_addInsight.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - CREATE TABLE IF NOT EXISTS "Insight" ( - "id" SERIAL PRIMARY KEY, - "teamId" VARCHAR(100) NOT NULL, - "startDateTime" TIMESTAMP WITH TIME ZONE NOT NULL, - "endDateTime" TIMESTAMP WITH TIME ZONE NOT NULL, - "wins" TEXT[] NOT NULL, - "challenges" TEXT[] NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL - ); - CREATE INDEX IF NOT EXISTS "idx_teamId" ON "Insight" ("teamId"); - CREATE INDEX IF NOT EXISTS "idx_startDateTime" ON "Insight" ("startDateTime"); - CREATE INDEX IF NOT EXISTS "idx_endDateTime" ON "Insight" ("endDateTime"); - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "Insight"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1723061869934_MeetingSettings-phase1.ts b/packages/server/postgres/migrations/1723061869934_MeetingSettings-phase1.ts deleted file mode 100644 index d8f1741cd7d..00000000000 --- a/packages/server/postgres/migrations/1723061869934_MeetingSettings-phase1.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'NewMeetingPhaseTypeEnum') THEN - CREATE TYPE "NewMeetingPhaseTypeEnum" AS ENUM ( - 'ESTIMATE', - 'SCOPE', - 'SUMMARY', - 'agendaitems', - 'checkin', - 'TEAM_HEALTH', - 'discuss', - 'firstcall', - 'group', - 'lastcall', - 'lobby', - 'reflect', - 'updates', - 'vote', - 'RESPONSES' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'MeetingTypeEnum') THEN - CREATE TYPE "MeetingTypeEnum" AS ENUM ( - 'action', - 'retrospective', - 'poker', - 'teamPrompt' - ); - END IF; - CREATE TABLE IF NOT EXISTS "MeetingSettings" ( - "id" VARCHAR(100) PRIMARY KEY, - "phaseTypes" "NewMeetingPhaseTypeEnum"[] NOT NULL, - "meetingType" "MeetingTypeEnum" NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "selectedTemplateId" VARCHAR(100), - "jiraSearchQueries" JSONB, - "maxVotesPerGroup" SMALLINT, - "totalVotes" SMALLINT, - "disableAnonymity" BOOLEAN, - "videoMeetingURL" VARCHAR(2056), - UNIQUE("teamId", "meetingType"), - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_selectedTemplateId" - FOREIGN KEY("selectedTemplateId") - REFERENCES "MeetingTemplate"("id") - ON DELETE SET NULL - ); - CREATE INDEX IF NOT EXISTS "idx_MeetingSettings_teamId" ON "MeetingSettings"("teamId"); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "MeetingSettings"; - DROP TYPE "NewMeetingPhaseTypeEnum"; - DROP TYPE "MeetingTypeEnum"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1723074637531_MeetingSettings-phase2.ts b/packages/server/postgres/migrations/1723074637531_MeetingSettings-phase2.ts deleted file mode 100644 index 1bb1e99f0a0..00000000000 --- a/packages/server/postgres/migrations/1723074637531_MeetingSettings-phase2.ts +++ /dev/null @@ -1,102 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - const MAX_PG_PARAMS = 65545 - - const PG_COLS = [ - 'id', - 'phaseTypes', - 'meetingType', - 'teamId', - 'selectedTemplateId', - 'jiraSearchQueries', - 'maxVotesPerGroup', - 'totalVotes', - 'disableAnonymity', - 'videoMeetingURL' - ] as const - type MeetingSettings = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - const startAt = new Date() - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curId) - let rawRowsToInsert = (await r - .table('MeetingSettings') - .between(curId, r.maxval, { - index: 'id', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'id'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as MeetingSettings[] - if (rawRowsToInsert.length === 0) { - // since we don't have a createdAt, it's possible new rows were created while this was running. - // Grab those new teams & get their settings, too - const newTeams = await pg - .selectFrom('Team') - .select('id') - .where('createdAt', '>', startAt) - .execute() - const newTeamIds = newTeams.map((team) => team.id) - console.log('got new TeamIds!', newTeamIds) - if (newTeamIds.length === 0) break - rawRowsToInsert = (await r - .table('MeetingSettings') - .getAll(r.args(newTeamIds)) - .pluck(...PG_COLS) - .run()) as MeetingSettings[] - } - const rowsToInsert = rawRowsToInsert.map((row) => ({ - ...row - })) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curId = lastRow.id - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('MeetingSettings') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId') { - // console.log(`Skipping ${row.id} because it has no team`) - return - } - if (e.constraint === 'fk_selectedTemplateId') { - // console.log(`Skipping ${row.id} because it has no template`) - return - } - console.log(e, row) - } - }) - ) - } -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "MeetingSettings" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1723491538114_AgendaItem-phase1.ts b/packages/server/postgres/migrations/1723491538114_AgendaItem-phase1.ts deleted file mode 100644 index cfa935f2a7c..00000000000 --- a/packages/server/postgres/migrations/1723491538114_AgendaItem-phase1.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "AgendaItem" ( - "id" VARCHAR(100) PRIMARY KEY, - "content" VARCHAR(64) NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - "isComplete" BOOLEAN NOT NULL DEFAULT FALSE, - "sortOrder" VARCHAR(64) NOT NULL COLLATE "C", - "teamId" VARCHAR(100) NOT NULL, - "teamMemberId" VARCHAR(100) NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL, - "meetingId" VARCHAR(100), - "pinned" BOOLEAN NOT NULL DEFAULT FALSE, - "pinnedParentId" VARCHAR(100), - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamMemberId" - FOREIGN KEY("teamMemberId") - REFERENCES "TeamMember"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_AgendaItem_teamId" ON "AgendaItem"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_AgendaItem_meetingId" ON "AgendaItem"("meetingId"); - CREATE INDEX IF NOT EXISTS "idx_AgendaItem_teamMemberId" ON "AgendaItem"("teamMemberId"); - DROP TRIGGER IF EXISTS "update_AgendaItem_updatedAt" ON "AgendaItem"; - CREATE TRIGGER "update_AgendaItem_updatedAt" BEFORE UPDATE ON "AgendaItem" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "AgendaItem"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1723492538114_MeetingSettings-phase2redo.ts b/packages/server/postgres/migrations/1723492538114_MeetingSettings-phase2redo.ts deleted file mode 100644 index 07da2947dfa..00000000000 --- a/packages/server/postgres/migrations/1723492538114_MeetingSettings-phase2redo.ts +++ /dev/null @@ -1,99 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - const MAX_PG_PARAMS = 65545 - - const PG_COLS = [ - 'id', - 'phaseTypes', - 'meetingType', - 'teamId', - 'selectedTemplateId', - 'jiraSearchQueries', - 'maxVotesPerGroup', - 'totalVotes', - 'disableAnonymity', - 'videoMeetingURL' - ] as const - type MeetingSettings = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - const handleInsert = async (row: MeetingSettings) => { - try { - await pg - .insertInto('MeetingSettings') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId') { - // console.log(`Skipping ${row.id} because it has no team`) - return - } - if (e.constraint === 'fk_selectedTemplateId') { - return handleInsert({...row, selectedTemplateId: null}) - } - console.log(e, row) - } - } - const startAt = new Date() - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, curId) - let rawRowsToInsert = (await r - .table('MeetingSettings') - .between(curId, r.maxval, { - index: 'id', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'id'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as MeetingSettings[] - if (rawRowsToInsert.length === 0) { - // since we don't have a createdAt, it's possible new rows were created while this was running. - // Grab those new teams & get their settings, too - const newTeams = await pg - .selectFrom('Team') - .select('id') - .where('createdAt', '>', startAt) - .execute() - const newTeamIds = newTeams.map((team) => team.id) - console.log('got new TeamIds!', newTeamIds) - if (newTeamIds.length === 0) break - rawRowsToInsert = (await r - .table('MeetingSettings') - .getAll(r.args(newTeamIds)) - .pluck(...PG_COLS) - .run()) as MeetingSettings[] - } - const rowsToInsert = rawRowsToInsert.map((row) => ({ - ...row - })) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curId = lastRow.id - await Promise.all(rowsToInsert.map(handleInsert)) - } -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "MeetingSettings" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1723672980596_AgendaItem-phase2.ts b/packages/server/postgres/migrations/1723672980596_AgendaItem-phase2.ts deleted file mode 100644 index 42a199bba9f..00000000000 --- a/packages/server/postgres/migrations/1723672980596_AgendaItem-phase2.ts +++ /dev/null @@ -1,184 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -const START_CHAR_CODE = 32 -const END_CHAR_CODE = 126 - -export function positionAfter(pos: string) { - for (let i = pos.length - 1; i >= 0; i--) { - const curCharCode = pos.charCodeAt(i) - if (curCharCode < END_CHAR_CODE) { - return pos.substr(0, i) + String.fromCharCode(curCharCode + 1) - } - } - return pos + String.fromCharCode(START_CHAR_CODE + 1) -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - // add a dummy date for nulls - const parabolEpoch = new Date('2016-06-01') - await r - .table('AgendaItem') - .update((row) => ({ - updatedAt: row('updatedAt').default(parabolEpoch), - createdAt: row('createdAt').default(parabolEpoch) - })) - .run() - const strDates = await r - .table('AgendaItem') - .filter((row) => row('updatedAt').typeOf().eq('STRING')) - .pluck('updatedAt', 'id', 'createdAt') - .run() - const dateDates = strDates.map((d) => ({ - id: d.id, - updatedAt: new Date(d.updatedAt), - createdAt: new Date(d.createdAt) - })) - // some dates are - await r(dateDates) - .forEach((row: any) => { - return r - .table('AgendaItem') - .get(row('id')) - .update({updatedAt: row('updatedAt')}) - }) - .run() - - try { - console.log('Adding index') - await r - .table('AgendaItem') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('AgendaItem').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'content', - 'createdAt', - 'isActive', - 'isComplete', - 'sortOrder', - 'teamId', - 'teamMemberId', - 'updatedAt', - 'meetingId', - 'pinned', - 'pinnedParentId' - ] as const - type AgendaItem = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('AgendaItem') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as AgendaItem[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const {sortOrder, ...rest} = row as any - return { - ...rest, - sortOrder: String(sortOrder) - } - }) - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - try { - await pg - .insertInto('AgendaItem') - .values(rowsToInsert) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('AgendaItem') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamMemberId' || e.constraint === 'fk_teamId') { - console.log(`Skipping ${row.id} because it has no user/team`) - return - } - console.log(e, row) - } - }) - ) - } - } - - // remap the sortOrder in PG because rethinkdb is too slow to group - const pgRows = await sql<{items: {sortOrder: string; id: string}[]}>` - select jsonb_agg(jsonb_build_object('sortOrder', "sortOrder", 'id', "id", 'meetingId', "meetingId", 'teamId', "teamId") ORDER BY "sortOrder") items from "AgendaItem" -group by "teamId", "meetingId";`.execute(pg) - - const groups = pgRows.rows.map((row) => { - const {items} = row - let curSortOrder = '' - for (let i = 0; i < items.length; i++) { - const item = items[i] - curSortOrder = positionAfter(curSortOrder) - item.sortOrder = curSortOrder - } - return row - }) - for (let i = 0; i < groups.length; i++) { - const group = groups[i] - await Promise.all( - group.items.map((item) => { - return pg - .updateTable('AgendaItem') - .set({sortOrder: item.sortOrder}) - .where('id', '=', item.id) - .execute() - }) - ) - } -} - -export async function down() { - // await connectRethinkDB() - // try { - // await r.table('AgendaItem').indexDrop('updatedAtId').run() - // } catch { - // // index already dropped - // } - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "AgendaItem" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1724174924811_oneTeamLead.ts b/packages/server/postgres/migrations/1724174924811_oneTeamLead.ts deleted file mode 100644 index c0d0da60ebf..00000000000 --- a/packages/server/postgres/migrations/1724174924811_oneTeamLead.ts +++ /dev/null @@ -1,47 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - const teamsWithout1Leader = await pg - .selectFrom('TeamMember') - .select('teamId') - .select(({fn}) => fn.count('id').as('count')) - .where('isNotRemoved', '=', true) - .groupBy('teamId') - .having(sql`SUM(CASE WHEN "isLead" = true THEN 1 ELSE 0 END) != 1`) - .execute() - - await Promise.all( - teamsWithout1Leader.map(async (row) => { - const {teamId} = row - // remove all leads for the cases where we had more than 1 - await pg.updateTable('TeamMember').set({isLead: false}).where('teamId', '=', teamId).execute() - await pg - .with('NextLead', (qb) => - qb - .selectFrom('TeamMember') - .select('id') - .where('teamId', '=', teamId) - .where('isNotRemoved', '=', true) - .orderBy('createdAt', 'asc') - .limit(1) - ) - .updateTable('TeamMember') - .set({isLead: true}) - .where(({eb, selectFrom}) => eb('id', '=', selectFrom('NextLead').select('id'))) - .returning('id') - .execute() - }) - ) -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1724261917988_SlackAuth.ts b/packages/server/postgres/migrations/1724261917988_SlackAuth.ts deleted file mode 100644 index 0a4549fe0e2..00000000000 --- a/packages/server/postgres/migrations/1724261917988_SlackAuth.ts +++ /dev/null @@ -1,108 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "SlackAuth" ( - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "id" VARCHAR(100) PRIMARY KEY, - "botUserId" VARCHAR(100) NOT NULL, - "botAccessToken" VARCHAR(100), - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "defaultTeamChannelId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - "slackTeamId" VARCHAR(100) NOT NULL, - "slackTeamName" VARCHAR(100) NOT NULL, - "slackUserId" VARCHAR(100) NOT NULL, - "slackUserName" VARCHAR(100) NOT NULL, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - UNIQUE("teamId", "userId") - ); - CREATE INDEX IF NOT EXISTS "idx_SlackAuth_teamId" ON "SlackAuth"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_SlackAuth_userId" ON "SlackAuth"("userId"); - DROP TRIGGER IF EXISTS "update_SlackAuth_updatedAt" ON "SlackAuth"; - CREATE TRIGGER "update_SlackAuth_updatedAt" BEFORE UPDATE ON "SlackAuth" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; -`.execute(pg) - - const rAuths = await r.table('SlackAuth').coerceTo('array').run() - - await Promise.all( - rAuths.map(async (auth) => { - const { - isActive, - updatedAt, - id, - botUserId, - botAccessToken, - createdAt, - defaultTeamChannelId, - teamId, - userId, - slackTeamId, - slackTeamName, - slackUserId, - slackUserName - } = auth - if (!botUserId || !botAccessToken) return - try { - return await pg - .insertInto('SlackAuth') - .values({ - isActive, - updatedAt, - id, - botUserId, - botAccessToken, - createdAt, - defaultTeamChannelId, - teamId, - userId, - slackTeamId, - slackTeamName, - slackUserId, - slackUserName - }) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId' || e.constraint === 'fk_userId') { - console.log(`Skipping ${auth.id} because it has no user/team`) - return - } - console.log(e, auth) - } - }) - ) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "SlackAuth"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1724358892236_SlackNotification.ts b/packages/server/postgres/migrations/1724358892236_SlackNotification.ts deleted file mode 100644 index f45b4be1c93..00000000000 --- a/packages/server/postgres/migrations/1724358892236_SlackNotification.ts +++ /dev/null @@ -1,79 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'SlackNotificationEventEnum') THEN - CREATE TYPE "SlackNotificationEventEnum" AS ENUM ( - 'meetingStart', - 'meetingEnd', - 'MEETING_STAGE_TIME_LIMIT_END', - 'MEETING_STAGE_TIME_LIMIT_START', - 'TOPIC_SHARED', - 'STANDUP_RESPONSE_SUBMITTED' - ); - END IF; - CREATE TABLE IF NOT EXISTS "SlackNotification" ( - "id" VARCHAR(100) PRIMARY KEY, - "event" "SlackNotificationEventEnum" NOT NULL, - "channelId" VARCHAR(100), - "teamId" VARCHAR(100) NOT NULL, - "userId" VARCHAR(100) NOT NULL, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - UNIQUE("teamId", "userId", "event") - ); - CREATE INDEX IF NOT EXISTS "idx_SlackNotification_teamId" ON "SlackNotification" ("teamId"); - CREATE INDEX IF NOT EXISTS "idx_SlackNotification_userId" ON "SlackNotification" ("userId"); - END $$; -`.execute(pg) - - const rNotifications = await r.table('SlackNotification').coerceTo('array').run() - - await Promise.all( - rNotifications.map(async (notification) => { - const {channelName, ...pgVal} = notification - try { - return await pg - .insertInto('SlackNotification') - .values(pgVal) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId' || e.constraint === 'fk_userId') { - console.log(`Skipping ${notification.id} because it has no user/team`) - return - } - console.log(e, notification) - } - }) - ) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TYPE "SlackNotificationEventEnum" CASCADE; - DROP TABLE IF EXISTS "SlackNotification"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1724780116674_Comment-phase1.ts b/packages/server/postgres/migrations/1724780116674_Comment-phase1.ts deleted file mode 100644 index 5090679072f..00000000000 --- a/packages/server/postgres/migrations/1724780116674_Comment-phase1.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "Comment" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "isActive" BOOLEAN NOT NULL DEFAULT TRUE, - "isAnonymous" BOOLEAN NOT NULL DEFAULT FALSE, - "threadParentId" VARCHAR(100), - "reactjis" "Reactji"[] NOT NULL DEFAULT array[]::"Reactji"[], - "content" JSONB NOT NULL, - "createdBy" VARCHAR(100), - "plaintextContent" VARCHAR(2000) NOT NULL, - "discussionId" VARCHAR(100) NOT NULL, - "threadSortOrder" INTEGER NOT NULL, - CONSTRAINT "fk_createdBy" - FOREIGN KEY("createdBy") - REFERENCES "User"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_discussionId" - FOREIGN KEY("discussionId") - REFERENCES "Discussion"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_Comment_threadParentId" ON "Comment"("threadParentId"); - CREATE INDEX IF NOT EXISTS "idx_Comment_createdBy" ON "Comment"("createdBy"); - CREATE INDEX IF NOT EXISTS "idx_Comment_discussionId" ON "Comment"("discussionId"); - END $$; -`) - // TODO add constraint threadParentId in phase 2 - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE "Comment"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1724884922936_Comment-phase2.ts b/packages/server/postgres/migrations/1724884922936_Comment-phase2.ts deleted file mode 100644 index 896774f9f81..00000000000 --- a/packages/server/postgres/migrations/1724884922936_Comment-phase2.ts +++ /dev/null @@ -1,140 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('Comment') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('Comment').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - // must truncate because some rows didn't have a threadParentId - await sql`TRUNCATE TABLE "Comment"`.execute(pg) - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'createdAt', - 'updatedAt', - 'isActive', - 'isAnonymous', - 'threadParentId', - 'reactjis', - 'content', - 'createdBy', - 'plaintextContent', - 'discussionId', - 'threadSortOrder' - ] as const - type Comment = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('Comment') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as Comment[] - - const rowsToInsert = rawRowsToInsert - .map((row) => { - const {plaintextContent, threadSortOrder, reactjis, ...rest} = row as any - return { - ...rest, - plaintextContent: plaintextContent.slice(0, 2000), - threadSortOrder: threadSortOrder ? Math.trunc(threadSortOrder) : 0, - reactjis: reactjis?.map((r: any) => `(${r.id},${r.userId})`) ?? [] - } - }) - .filter((row) => row.discussionId) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('Comment') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_createdBy') { - await pg - .insertInto('Comment') - .values({...row, createdBy: null}) - .onConflict((oc) => oc.doNothing()) - .execute() - return - } - if (e.constraint === 'fk_discussionId') { - console.log(`Skipping ${row.id} because it has no discussion`) - return - } - console.log(e, row) - } - }) - ) - } - - // if the threadParentId references an id that does not exist, set it to null - console.log('adding threadParentId constraint') - await pg - .updateTable('Comment') - .set({threadParentId: null}) - .where(({eb, selectFrom}) => - eb( - 'id', - 'in', - selectFrom('Comment as child') - .select('child.id') - .leftJoin('Comment as parent', 'child.threadParentId', 'parent.id') - .where('parent.id', 'is', null) - .where('child.threadParentId', 'is not', null) - ) - ) - .execute() - await pg.schema - .alterTable('Comment') - .addForeignKeyConstraint('fk_threadParentId', ['threadParentId'], 'Comment', ['id']) - .onDelete('set null') - .execute() -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "Comment" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1725438336254_addOrganizationUserUniqueConstraint.ts b/packages/server/postgres/migrations/1725438336254_addOrganizationUserUniqueConstraint.ts deleted file mode 100644 index adb0eb29a54..00000000000 --- a/packages/server/postgres/migrations/1725438336254_addOrganizationUserUniqueConstraint.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - // get rid of duplicates - // no kysely here, because I tested the SQL directly and don't want to touch it - await sql` - DELETE FROM "OrganizationUser" d USING "OrganizationUser" k - WHERE d."userId" = k."userId" - AND d."orgId" = k."orgId" - AND ( - -- keep non-removed over removed - (k."removedAt" IS NULL AND d."removedAt" IS NOT NULL) - -- or removed later - OR (k."removedAt" IS NOT NULL - AND d."removedAt" IS NOT NULL - AND (k."removedAt" > d."removedAt" - OR ((k."removedAt" = d."removedAt") AND k.id > d.id) - ) - ) - -- or newer non-removed - OR (k."removedAt" IS NULL AND d."removedAt" IS NULL AND k.id > d.id) - ); - `.execute(pg) - - await pg.schema - .alterTable('OrganizationUser') - .addUniqueConstraint('unique_org_user', ['orgId', 'userId']) - .execute() -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.schema.alterTable('OrganizationUser').dropConstraint('unique_org_user').execute() -} diff --git a/packages/server/postgres/migrations/1725655687704_ReflectPrompt-phase1.ts b/packages/server/postgres/migrations/1725655687704_ReflectPrompt-phase1.ts deleted file mode 100644 index 425985da005..00000000000 --- a/packages/server/postgres/migrations/1725655687704_ReflectPrompt-phase1.ts +++ /dev/null @@ -1,56 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "ReflectPrompt" ( - "id" VARCHAR(100) PRIMARY KEY, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "removedAt" TIMESTAMP WITH TIME ZONE, - "description" VARCHAR(256) NOT NULL, - "groupColor" VARCHAR(9) NOT NULL, - "sortOrder" VARCHAR(64) NOT NULL COLLATE "C", - "question" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "templateId" VARCHAR(100) NOT NULL, - "parentPromptId" VARCHAR(100), - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_templateId" - FOREIGN KEY("templateId") - REFERENCES "MeetingTemplate"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_ReflectPrompt_teamId" ON "ReflectPrompt"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_ReflectPrompt_templateId" ON "ReflectPrompt"("templateId"); - CREATE INDEX IF NOT EXISTS "idx_ReflectPrompt_parentPromptId" ON "ReflectPrompt"("templateId"); - CREATE OR REPLACE TRIGGER "update_MeetingTemplate_updatedAt_from_ReflectPrompt" - AFTER INSERT OR UPDATE OR DELETE ON "ReflectPrompt" - FOR EACH ROW - EXECUTE FUNCTION "set_MeetingTemplate_updatedAt"(); - END $$; -`) - // TODO add constraint parentPromptId constraint - // CONSTRAINT "fk_parentPromptId" - // FOREIGN KEY("parentPromptId") - // REFERENCES "MeetingTemplate"("id") - // ON DELETE CASCADE - - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "ReflectPrompt"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1725913333530_ReflectPrompt-phase2.ts b/packages/server/postgres/migrations/1725913333530_ReflectPrompt-phase2.ts deleted file mode 100644 index 5654c71dc22..00000000000 --- a/packages/server/postgres/migrations/1725913333530_ReflectPrompt-phase2.ts +++ /dev/null @@ -1,169 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -const START_CHAR_CODE = 32 -const END_CHAR_CODE = 126 - -export function positionAfter(pos: string) { - for (let i = pos.length - 1; i >= 0; i--) { - const curCharCode = pos.charCodeAt(i) - if (curCharCode < END_CHAR_CODE) { - return pos.substr(0, i) + String.fromCharCode(curCharCode + 1) - } - } - return pos + String.fromCharCode(START_CHAR_CODE + 1) -} - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('ReflectPrompt') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('ReflectPrompt').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'createdAt', - 'updatedAt', - 'removedAt', - 'description', - 'groupColor', - 'sortOrder', - 'question', - 'teamId', - 'templateId', - 'parentPromptId' - ] as const - type ReflectPrompt = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('ReflectPrompt') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as ReflectPrompt[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const {description, groupColor, sortOrder, question, ...rest} = row as any - return { - ...rest, - description: description?.slice(0, 256) ?? '', - groupColor: groupColor?.slice(0, 9) ?? '#66BC8C', - sortOrder: String(sortOrder), - question: question?.slice(0, 100) ?? '' - } - }) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - await Promise.all( - rowsToInsert.map(async (row) => { - try { - await pg - .insertInto('ReflectPrompt') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_templateId' || e.constraint === 'fk_teamId') { - console.log('Missing templateId or teamId', row.id) - return - } - console.log(e, row) - } - }) - ) - } - - // remap the sortOrder in PG because rethinkdb is too slow to group - console.log('Correcting sortOrder') - const pgRows = await sql<{items: {sortOrder: string; id: string}[]}>` - select jsonb_agg(jsonb_build_object('sortOrder', "sortOrder", 'id', "id", 'templateId', "templateId") ORDER BY "sortOrder") items from "ReflectPrompt" -group by "templateId";`.execute(pg) - - const groups = pgRows.rows.map((row) => { - const {items} = row - let curSortOrder = '' - for (let i = 0; i < items.length; i++) { - const item = items[i] - curSortOrder = positionAfter(curSortOrder) - item.sortOrder = curSortOrder - } - return row - }) - for (let i = 0; i < groups.length; i++) { - const group = groups[i] - await Promise.all( - group.items.map((item) => { - return pg - .updateTable('ReflectPrompt') - .set({sortOrder: item.sortOrder}) - .where('id', '=', item.id) - .execute() - }) - ) - } - - // if the threadParentId references an id that does not exist, set it to null - console.log('adding parentPromptId constraint') - await pg - .updateTable('ReflectPrompt') - .set({parentPromptId: null}) - .where(({eb, selectFrom}) => - eb( - 'id', - 'in', - selectFrom('ReflectPrompt as child') - .select('child.id') - .leftJoin('ReflectPrompt as parent', 'child.parentPromptId', 'parent.id') - .where('parent.id', 'is', null) - .where('child.parentPromptId', 'is not', null) - ) - ) - .execute() - await pg.schema - .alterTable('ReflectPrompt') - .addForeignKeyConstraint('fk_parentPromptId', ['parentPromptId'], 'ReflectPrompt', ['id']) - .onDelete('set null') - .execute() -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "ReflectPrompt" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1725996598345_PasswordResetRequest.ts b/packages/server/postgres/migrations/1725996598345_PasswordResetRequest.ts deleted file mode 100644 index b949a622405..00000000000 --- a/packages/server/postgres/migrations/1725996598345_PasswordResetRequest.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "PasswordResetRequest" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "ip" cidr NOT NULL, - "email" "citext" NOT NULL, - "time" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "token" VARCHAR(64) NOT NULL, - "isValid" BOOLEAN NOT NULL DEFAULT TRUE - ); - CREATE INDEX IF NOT EXISTS "idx_PasswordResetRequest_ip" ON "PasswordResetRequest"("ip"); - CREATE INDEX IF NOT EXISTS "idx_PasswordResetRequest_email" ON "PasswordResetRequest"("email"); - CREATE INDEX IF NOT EXISTS "idx_PasswordResetRequest_token" ON "PasswordResetRequest"("token"); - END $$; -`.execute(pg) - - const rRequests = await r.table('PasswordResetRequest').coerceTo('array').run() - - await Promise.all( - rRequests.map(async (row) => { - const {ip, email, time, token, isValid} = row - try { - return await pg - .insertInto('PasswordResetRequest') - .values({ - ip, - email, - time, - token, - isValid - }) - .execute() - } catch (e) { - console.log(e, row) - } - }) - ) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "PasswordResetRequest"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1726078121329_PushInvitation.ts b/packages/server/postgres/migrations/1726078121329_PushInvitation.ts deleted file mode 100644 index aedaeda9c87..00000000000 --- a/packages/server/postgres/migrations/1726078121329_PushInvitation.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "PushInvitation" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "userId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "denialCount" SMALLINT NOT NULL DEFAULT 0, - "lastDenialAt" TIMESTAMP WITH TIME ZONE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE SET NULL - ); - CREATE INDEX IF NOT EXISTS "idx_PushInvitation_userId" ON "PushInvitation"("userId"); - CREATE INDEX IF NOT EXISTS "idx_PushInvitation_teamId" ON "PushInvitation"("teamId"); - END $$; -`.execute(pg) - - const rRequests = await r.table('PushInvitation').coerceTo('array').run() - - await Promise.all( - rRequests.map(async (row) => { - const {userId, teamId, denialCount, lastDenialAt} = row - try { - return await pg - .insertInto('PushInvitation') - .values({ - userId, - teamId, - denialCount, - lastDenialAt - }) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId') { - console.log(`Skipping ${row.id} because it has no valid teamId`) - return - } - if (e.constraint === 'fk_userId') { - console.log(`Skipping ${row.id} because it has no valid userId`) - return - } - console.log(e, row) - } - }) - ) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "PushInvitation"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1726174443131_dropThreadParentId.ts b/packages/server/postgres/migrations/1726174443131_dropThreadParentId.ts deleted file mode 100644 index b7341660ebe..00000000000 --- a/packages/server/postgres/migrations/1726174443131_dropThreadParentId.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import {Client} from 'pg' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - // threadParentId can exist outside comment table (task, poll, etc) - await client.query( - `ALTER TABLE "Comment" DROP CONSTRAINT IF EXISTS "fk_threadParentId";` /* Do good magic */ - ) - await client.end() -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await pg.schema - .alterTable('Comment') - .addForeignKeyConstraint('fk_threadParentId', ['threadParentId'], 'Comment', ['id']) - .onDelete('set null') - .execute() -} diff --git a/packages/server/postgres/migrations/1726174453131_NewMeeting-phase1.ts b/packages/server/postgres/migrations/1726174453131_NewMeeting-phase1.ts deleted file mode 100644 index 87318cabb7a..00000000000 --- a/packages/server/postgres/migrations/1726174453131_NewMeeting-phase1.ts +++ /dev/null @@ -1,99 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - - // Notable changes - // - SlackTs is now a double precision - // - facilitatorUserId is nullable in the case of a user hard delete - // - hasScheduledEndTime index changed to scheduledEndTime - - await client.query(` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "NewMeeting" ( - "id" VARCHAR(100) PRIMARY KEY, - "isLegacy" BOOLEAN NOT NULL DEFAULT FALSE, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "createdBy" VARCHAR(100), - "endedAt" TIMESTAMP WITH TIME ZONE, - "facilitatorStageId" VARCHAR(100) NOT NULL, - "facilitatorUserId" VARCHAR(100), - "meetingCount" INT NOT NULL, - "meetingNumber" INT NOT NULL, - "name" VARCHAR(100) NOT NULL, - "summarySentAt" TIMESTAMP WITH TIME ZONE, - "teamId" VARCHAR(100) NOT NULL, - "meetingType" "MeetingTypeEnum" NOT NULL, - "phases" JSONB NOT NULL, - "showConversionModal" BOOLEAN NOT NULL DEFAULT FALSE, - "meetingSeriesId" INT, - "scheduledEndTime" TIMESTAMP WITH TIME ZONE, - "summary" VARCHAR(10000), - "sentimentScore" DOUBLE PRECISION, - "usedReactjis" JSONB, - "slackTs" DOUBLE PRECISION, - "engagement" DOUBLE PRECISION, - "totalVotes" INT, - "maxVotesPerGroup" SMALLINT, - "disableAnonymity" BOOLEAN, - "commentCount" INT, - "taskCount" INT, - "agendaItemCount" INT, - "storyCount" INT, - "templateId" VARCHAR(100), - "topicCount" INT, - "reflectionCount" INT, - "transcription" JSONB, - "recallBotId" VARCHAR(255), - "videoMeetingURL" VARCHAR(2048), - "autogroupReflectionGroups" JSONB, - "resetReflectionGroups" JSONB, - "templateRefId" VARCHAR(25), - "meetingPrompt" VARCHAR(255), - CONSTRAINT "fk_createdBy" - FOREIGN KEY("createdBy") - REFERENCES "User"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_facilitatorUserId" - FOREIGN KEY("facilitatorUserId") - REFERENCES "User"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_meetingSeriesId" - FOREIGN KEY("meetingSeriesId") - REFERENCES "MeetingSeries"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_templateId" - FOREIGN KEY("templateId") - REFERENCES "MeetingTemplate"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_NewMeeting_createdAt" ON "NewMeeting"("createdAt"); - CREATE INDEX IF NOT EXISTS "idx_NewMeeting_facilitatorUserId" ON "NewMeeting"("facilitatorUserId"); - CREATE INDEX IF NOT EXISTS "idx_NewMeeting_scheduledEndTime" ON "NewMeeting"("scheduledEndTime") WHERE "scheduledEndTime" IS NOT NULL AND "endedAt" IS NULL; - CREATE INDEX IF NOT EXISTS "idx_NewMeeting_meetingSeriesId" ON "NewMeeting"("meetingSeriesId") WHERE "meetingSeriesId" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_NewMeeting_teamId" ON "NewMeeting"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_NewMeeting_templateId" ON "NewMeeting"("templateId") WHERE "templateId" IS NOT NULL; - DROP TRIGGER IF EXISTS "update_NewMeeting_updatedAt" ON "NewMeeting"; - CREATE TRIGGER "update_NewMeeting_updatedAt" BEFORE UPDATE ON "NewMeeting" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; -`) - - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "NewMeeting"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1726251201860_NewMeeting-uniq.ts b/packages/server/postgres/migrations/1726251201860_NewMeeting-uniq.ts deleted file mode 100644 index 5bdf1e5a27d..00000000000 --- a/packages/server/postgres/migrations/1726251201860_NewMeeting-uniq.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - // Doing this as a trigger instead of making unique teamId/meetingType/createdAt because rounding createdAt to the nearest 5 seconds felt bad - sql` - CREATE OR REPLACE FUNCTION prevent_meeting_overlap() - RETURNS TRIGGER AS $$ - BEGIN - -- Check if a meeting exists within a 2-second window of the new createdAt - IF EXISTS ( - SELECT 1 FROM "NewMeeting" - WHERE "teamId" = NEW."teamId" - AND "meetingType" = NEW."meetingType" - AND ABS(EXTRACT(EPOCH FROM (NEW."createdAt" - "createdAt"))) < 2 - ) THEN - RAISE EXCEPTION 'Cannot insert meeting. A meeting exists within a 2-second window.'; - END IF; - -- If no conflict, allow the insert - RETURN NEW; - END; - $$ LANGUAGE plpgsql; - DROP TRIGGER IF EXISTS "check_meeting_overlap" ON "NewMeeting"; - CREATE TRIGGER "check_meeting_overlap" - BEFORE INSERT ON "NewMeeting" - FOR EACH ROW - EXECUTE FUNCTION prevent_meeting_overlap(); - `.execute(pg) -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`DROP TRIGGER IF EXISTS "check_meeting_overlap" ON "NewMeeting";`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1726602922665_NewMeeting-phase2.ts b/packages/server/postgres/migrations/1726602922665_NewMeeting-phase2.ts deleted file mode 100644 index cdb45ed0b34..00000000000 --- a/packages/server/postgres/migrations/1726602922665_NewMeeting-phase2.ts +++ /dev/null @@ -1,170 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('NewMeeting') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('NewMeeting').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - await sql`ALTER TABLE "NewMeeting" DISABLE TRIGGER "check_meeting_overlap"`.execute(pg) - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'isLegacy', - 'createdAt', - 'updatedAt', - 'createdBy', - 'endedAt', - 'facilitatorStageId', - 'facilitatorUserId', - 'meetingCount', - 'meetingNumber', - 'name', - 'summarySentAt', - 'teamId', - 'meetingType', - 'phases', - 'showConversionModal', - 'meetingSeriesId', - 'scheduledEndTime', - 'summary', - 'sentimentScore', - 'usedReactjis', - 'slackTs', - 'engagement', - 'totalVotes', - 'maxVotesPerGroup', - 'disableAnonymity', - 'commentCount', - 'taskCount', - 'agendaItemCount', - 'storyCount', - 'templateId', - 'topicCount', - 'reflectionCount', - 'transcription', - 'recallBotId', - 'videoMeetingURL', - 'autogroupReflectionGroups', - 'resetReflectionGroups', - 'templateRefId', - 'meetingPrompt' - ] as const - type NewMeeting = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - - const insertRow = async (row) => { - if (!row.facilitatorStageId) { - console.log('Meeting has no facilitatorId, skipping insert', row.id, row.teamId) - return - } - try { - await pg - .insertInto('NewMeeting') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_createdBy') { - return insertRow({...row, createdBy: null}) - } - if (e.constraint === 'fk_facilitatorUserId') { - return insertRow({...row, facilitatorUserId: null}) - } - if (e.constraint === 'fk_teamId') { - console.log('Meeting has no team, skipping insert', row.id) - return - } - if (e.constraint === 'fk_meetingSeriesId') { - return insertRow({...row, meetingSeriesId: null}) - } - if (e.constraint === 'fk_templateId') { - console.log('Meeting has no template, skipping insert', row.id) - return - } - throw e - } - } - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('NewMeeting') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as NewMeeting[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const { - phases, - name, - summary, - usedReactjis, - slackTs, - transcription, - autogroupReflectionGroups, - resetReflectionGroups, - meetingPrompt, - meetingCount, - ...rest - } = row as any - return { - ...rest, - phases: JSON.stringify(phases), - name: name.slice(0, 100), - summary: summary ? summary.slice(0, 10000) : null, - usedReactjis: JSON.stringify(usedReactjis), - slackTs: isNaN(Number(slackTs)) ? null : Number(slackTs), - transcription: JSON.stringify(transcription), - autogroupReflectionGroups: JSON.stringify(autogroupReflectionGroups), - resetReflectionGroups: JSON.stringify(resetReflectionGroups), - meetingPrompt: meetingPrompt ? meetingPrompt.slice(0, 255) : null, - meetingCount: meetingCount || 0 - } - }) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - await Promise.all(rowsToInsert.map(async (row) => insertRow(row))) - } - await sql`ALTER TABLE "NewMeeting" ENABLE TRIGGER "check_meeting_overlap"`.execute(pg) -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "NewMeeting" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1727249259984_addFeatureFlagTables.ts b/packages/server/postgres/migrations/1727249259984_addFeatureFlagTables.ts deleted file mode 100644 index 7b84d353ab9..00000000000 --- a/packages/server/postgres/migrations/1727249259984_addFeatureFlagTables.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema.createType('FeatureFlagScope').asEnum(['User', 'Team', 'Organization']).execute() - - await pg.schema - .createTable('FeatureFlag') - .ifNotExists() - .addColumn('id', 'uuid', (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)) - .addColumn('featureName', 'varchar(255)', (col) => col.notNull()) - .addColumn('scope', sql`"FeatureFlagScope"`, (col) => col.notNull()) - .addColumn('description', 'text') - .addColumn('expiresAt', 'timestamptz', (col) => col.notNull()) - .addColumn('createdAt', 'timestamptz', (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)) - .addColumn('updatedAt', 'timestamptz', (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)) - .addUniqueConstraint('unique_featureName_scope', ['featureName', 'scope']) - .execute() - - await pg.schema - .createTable('FeatureFlagOwner') - .ifNotExists() - .addColumn('featureFlagId', 'uuid', (col) => - col.notNull().references('FeatureFlag.id').onDelete('cascade') - ) - .addColumn('userId', 'varchar(255)', (col) => col.references('User.id').onDelete('cascade')) - .addColumn('teamId', 'varchar(255)', (col) => col.references('Team.id').onDelete('cascade')) - .addColumn('orgId', 'varchar(255)', (col) => - col.references('Organization.id').onDelete('cascade') - ) - .addColumn('createdAt', 'timestamptz', (col) => col.notNull().defaultTo(sql`CURRENT_TIMESTAMP`)) - .addCheckConstraint( - 'check_feature_flag_owner_exclusivity', - sql` - (("userId" IS NOT NULL AND "teamId" IS NULL AND "orgId" IS NULL) OR - ("userId" IS NULL AND "teamId" IS NOT NULL AND "orgId" IS NULL) OR - ("userId" IS NULL AND "teamId" IS NULL AND "orgId" IS NOT NULL)) - ` - ) - .addUniqueConstraint('unique_feature_flag_owner_user', ['userId', 'featureFlagId']) - .addUniqueConstraint('unique_feature_flag_owner_team', ['teamId', 'featureFlagId']) - .addUniqueConstraint('unique_feature_flag_owner_org', ['orgId', 'featureFlagId']) - .execute() -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.schema.dropTable('FeatureFlagOwner').execute() - await pg.schema.dropTable('FeatureFlag').execute() - await pg.schema.dropType('FeatureFlagScope').execute() // Drop the enum type -} diff --git a/packages/server/postgres/migrations/1727885996466_migrateFeatureFlags.ts b/packages/server/postgres/migrations/1727885996466_migrateFeatureFlags.ts deleted file mode 100644 index b5eac845af5..00000000000 --- a/packages/server/postgres/migrations/1727885996466_migrateFeatureFlags.ts +++ /dev/null @@ -1,64 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - const FIFTY_YEARS_FROM_NOW = new Date(Date.now() + 50 * 365 * 24 * 60 * 60 * 1000) - - await pg.transaction().execute(async (trx) => { - const insertResult = await trx - .insertInto('FeatureFlag') - .values({ - featureName: 'noAISummary', - scope: 'Organization', - description: 'Disables AI summary feature', - expiresAt: FIFTY_YEARS_FROM_NOW - }) - .returning('id') - .executeTakeFirstOrThrow() - - const featureFlagId = insertResult.id - - await sql` - INSERT INTO "FeatureFlagOwner" ("featureFlagId", "orgId") - SELECT ${featureFlagId} AS "featureFlagId", "id" AS "orgId" - FROM "Organization" - WHERE "featureFlags" @> ARRAY['noAISummary']::text[]; - `.execute(trx) - - await sql` - INSERT INTO "FeatureFlagOwner" ("featureFlagId", "orgId") - SELECT DISTINCT ON ("OrganizationUser"."orgId") - ${featureFlagId} AS "featureFlagId", - "OrganizationUser"."orgId" AS "orgId" - FROM "User" - INNER JOIN "OrganizationUser" ON "OrganizationUser"."userId" = "User"."id" - WHERE "User"."featureFlags" @> ARRAY['noAISummary']::varchar(50)[] - ON CONFLICT ("featureFlagId", "orgId") DO NOTHING; - `.execute(trx) - }) -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg.transaction().execute(async (trx) => { - await trx - .deleteFrom('FeatureFlagOwner') - .using('FeatureFlag') - .where('FeatureFlagOwner.featureFlagId', '=', sql.ref('FeatureFlag.id')) - .where('FeatureFlag.featureName', '=', 'noAISummary') - .execute() - - await trx.deleteFrom('FeatureFlag').where('featureName', '=', 'noAISummary').execute() - }) -} diff --git a/packages/server/postgres/migrations/1727893031268_MeetingMember-phase1.ts b/packages/server/postgres/migrations/1727893031268_MeetingMember-phase1.ts deleted file mode 100644 index d0c0eabfabb..00000000000 --- a/packages/server/postgres/migrations/1727893031268_MeetingMember-phase1.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "MeetingMember" ( - "id" VARCHAR(100) PRIMARY KEY, - "meetingType" "MeetingTypeEnum" NOT NULL, - "meetingId" VARCHAR(100) NOT NULL, - "teamId" VARCHAR(100) NOT NULL, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "userId" VARCHAR(100) NOT NULL, - "isSpectating" BOOLEAN, - "votesRemaining" SMALLINT, - CONSTRAINT "fk_meetingId" - FOREIGN KEY("meetingId") - REFERENCES "NewMeeting"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_MeetingMember_meetingId" ON "MeetingMember"("meetingId"); - CREATE INDEX IF NOT EXISTS "idx_MeetingMember_teamId" ON "MeetingMember"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_MeetingMember_userId" ON "MeetingMember"("userId"); - DROP TRIGGER IF EXISTS "update_MeetingMember_updatedAt" ON "MeetingMember"; - CREATE TRIGGER "update_MeetingMember_updatedAt" BEFORE UPDATE ON "MeetingMember" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - END $$; -`) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "MeetingMember"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1727995266026_MeetingMember-phase2.ts b/packages/server/postgres/migrations/1727995266026_MeetingMember-phase2.ts deleted file mode 100644 index 650075cde3c..00000000000 --- a/packages/server/postgres/migrations/1727995266026_MeetingMember-phase2.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('MeetingMember') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('MeetingMember').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'meetingType', - 'meetingId', - 'teamId', - 'updatedAt', - 'userId', - 'isSpectating', - 'votesRemaining' - ] as const - type MeetingMember = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - - const insertRow = async (row) => { - if (!row.teamId) { - console.log('MeetingMember has no teamId, skipping insert', row.id) - return - } - try { - await pg - .insertInto('MeetingMember') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId') { - console.log('MeetingMember has no team, skipping insert', row.id) - return - } - if (e.constraint === 'fk_meetingId') { - console.log('MeetingMember has no meeting, skipping insert', row.id) - return - } - if (e.constraint === 'fk_userId') { - console.log('MeetingMember has no user, skipping insert', row.id) - return - } - throw e - } - } - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('MeetingMember') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as MeetingMember[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const {id, meetingType, meetingId, teamId, updatedAt, userId, isSpectating, votesRemaining} = - row as any - return { - id, - meetingType, - meetingId, - teamId, - updatedAt, - userId, - isSpectating, - votesRemaining - } - }) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - await Promise.all(rowsToInsert.map(async (row) => insertRow(row))) - } -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "MeetingMember" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1728411506375_MassInvitation-1shot.ts b/packages/server/postgres/migrations/1728411506375_MassInvitation-1shot.ts deleted file mode 100644 index 09a93e8853a..00000000000 --- a/packages/server/postgres/migrations/1728411506375_MassInvitation-1shot.ts +++ /dev/null @@ -1,71 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "MassInvitation" ( - "id" CHAR(12) NOT NULL PRIMARY KEY, - "expiration" TIMESTAMP WITH TIME ZONE NOT NULL, - "meetingId" VARCHAR(100), - "teamMemberId" VARCHAR(100) NOT NULL, - CONSTRAINT "fk_meetingId" - FOREIGN KEY("meetingId") - REFERENCES "NewMeeting"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamMemberId" - FOREIGN KEY("teamMemberId") - REFERENCES "TeamMember"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_MassInvitation_meetingId" ON "MassInvitation"("meetingId") WHERE "meetingId" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_MassInvitation_teamMemberId" ON "MassInvitation"("teamMemberId"); - END $$; -`.execute(pg) - - const rRequests = await r - .table('MassInvitation') - .filter((row) => row('expiration').ge(r.now())) - .coerceTo('array') - .run() - - const insertRow = async (row) => { - try { - await pg - .insertInto('MassInvitation') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_meetingId') { - return insertRow({...row, meetingId: null}) - } - if (e.constraint === 'fk_teamMemberId') { - console.log('MassInvitation has no teamMember, skipping insert', row.id) - return - } - throw e - } - } - await Promise.all(rRequests.map(async (row) => insertRow(row))) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "MassInvitation"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1728418948136_NewFeature-oneshot.ts b/packages/server/postgres/migrations/1728418948136_NewFeature-oneshot.ts deleted file mode 100644 index 2b6e137980f..00000000000 --- a/packages/server/postgres/migrations/1728418948136_NewFeature-oneshot.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "NewFeature" ( - "id" INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - "actionButtonCopy" VARCHAR(50) NOT NULL, - "snackbarMessage" VARCHAR(255) NOT NULL, - "url" VARCHAR(2056) NOT NULL - ); - END $$; -`.execute(pg) - - // empty out old new features, do not migrate them over - await pg.updateTable('User').set({newFeatureId: null}).execute() - await pg.schema - .alterTable('User') - .alterColumn('newFeatureId', (builder) => - builder.setDataType(sql`INTEGER USING "newFeatureId"::integer`) - ) - .execute() - await pg.schema - .alterTable('User') - .addForeignKeyConstraint('fk_newFeatureId', ['newFeatureId'], 'NewFeature', ['id']) - .onDelete('set null') - .execute() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "NewFeature"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1728425112300_TeamInvitation-phase1.ts b/packages/server/postgres/migrations/1728425112300_TeamInvitation-phase1.ts deleted file mode 100644 index 875feca6b68..00000000000 --- a/packages/server/postgres/migrations/1728425112300_TeamInvitation-phase1.ts +++ /dev/null @@ -1,60 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - CREATE TABLE IF NOT EXISTS "TeamInvitation" ( - "id" VARCHAR(100) NOT NULL PRIMARY KEY, - "acceptedAt" TIMESTAMP WITH TIME ZONE, - "acceptedBy" VARCHAR(100), - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, - "email" "citext" NOT NULL, - "invitedBy" VARCHAR(100) NOT NULL, - "isMassInvite" BOOLEAN NOT NULL DEFAULT FALSE, - "meetingId" VARCHAR(100), - "teamId" VARCHAR(100) NOT NULL, - "token" VARCHAR(200) NOT NULL, - CONSTRAINT "fk_meetingId" - FOREIGN KEY("meetingId") - REFERENCES "NewMeeting"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_invitedBy" - FOREIGN KEY("invitedBy") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_acceptedBy" - FOREIGN KEY("acceptedBy") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_TeamInvitation_email" ON "TeamInvitation"("email"); - CREATE INDEX IF NOT EXISTS "idx_TeamInvitation_teamId" ON "TeamInvitation"("teamId"); - CREATE INDEX IF NOT EXISTS "idx_TeamInvitation_token" ON "TeamInvitation"("token"); - END $$; -`.execute(pg) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "TeamInvitation"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1728496970486_TeamInvitation-phase2.ts b/packages/server/postgres/migrations/1728496970486_TeamInvitation-phase2.ts deleted file mode 100644 index 54271a6721e..00000000000 --- a/packages/server/postgres/migrations/1728496970486_TeamInvitation-phase2.ts +++ /dev/null @@ -1,134 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('TeamInvitation') - .indexCreate('updatedAtId', (row: any) => [row('expiresAt'), row('id')]) - .run() - await r.table('TeamInvitation').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'acceptedAt', - 'acceptedBy', - 'createdAt', - 'expiresAt', - 'email', - 'invitedBy', - 'isMassInvite', - 'meetingId', - 'teamId', - 'token' - ] as const - type TeamInvitation = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = new Date() - let curId = r.minval - - const insertRow = async (row) => { - try { - await pg - .insertInto('TeamInvitation') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId') { - console.log('TeamInvitation has no team, skipping insert', row.id) - return - } - if (e.constraint === 'fk_meetingId') { - console.log('TeamInvitation has no meeting, skipping insert', row.id) - return - } - if (e.constraint === 'fk_acceptedBy') { - console.log('TeamInvitation has no acceptedBy user, skipping insert', row.id) - return - } - if (e.constraint === 'fk_invitedBy') { - console.log('TeamInvitation has no invitedBy user, skipping insert', row.id) - return - } - throw e - } - } - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('TeamInvitation') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as TeamInvitation[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const { - id, - acceptedAt, - acceptedBy, - createdAt, - expiresAt, - email, - invitedBy, - isMassInvite, - meetingId, - teamId, - token - } = row as any - return { - id, - acceptedAt, - acceptedBy, - createdAt, - expiresAt, - email, - invitedBy, - isMassInvite, - meetingId, - teamId, - token - } - }) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.expiresAt - curId = lastRow.id - await Promise.all(rowsToInsert.map(async (row) => insertRow(row))) - } -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "TeamInvitation" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1728496980486_removeOldInviteNotifs.ts b/packages/server/postgres/migrations/1728496980486_removeOldInviteNotifs.ts deleted file mode 100644 index a0e42195d52..00000000000 --- a/packages/server/postgres/migrations/1728496980486_removeOldInviteNotifs.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' - -export async function up() { - await connectRethinkDB() - const almostAMonthAgo = new Date(Date.now() - 29 * 24 * 60 * 60 * 1000) - await r - .table('Notification') - .filter({type: 'TEAM_INVITATION'}) - .filter((row) => row('createdAt').le(almostAMonthAgo)) - .delete() - .run() -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1728578190454_Task-phase1.ts b/packages/server/postgres/migrations/1728578190454_Task-phase1.ts deleted file mode 100644 index 7fba8b32c38..00000000000 --- a/packages/server/postgres/migrations/1728578190454_Task-phase1.ts +++ /dev/null @@ -1,97 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TaskStatusEnum') THEN - CREATE TYPE "TaskStatusEnum" AS ENUM ( - 'active', - 'stuck', - 'done', - 'future' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TaskTagEnum') THEN - CREATE TYPE "TaskTagEnum" AS ENUM ( - 'private', - 'archived' - ); - END IF; - CREATE TABLE IF NOT EXISTS "Task" ( - "id" VARCHAR(100) NOT NULL PRIMARY KEY, - "content" JSONB NOT NULL, - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "createdBy" VARCHAR(100) NOT NULL, - "doneMeetingId" VARCHAR(100), - "dueDate" TIMESTAMP WITH TIME ZONE, - "integration" JSONB, - "integrationHash" VARCHAR(200), - "meetingId" VARCHAR(100), - "plaintextContent" VARCHAR(10000) NOT NULL, - "sortOrder" DOUBLE PRECISION NOT NULL DEFAULT 0, - "status" "TaskStatusEnum" NOT NULL DEFAULT 'active', - "tags" "TaskTagEnum"[] NOT NULL DEFAULT ARRAY[]::"TaskTagEnum"[], - "teamId" VARCHAR(100) NOT NULL, - "discussionId" VARCHAR(100), - "threadParentId" VARCHAR(100), - "threadSortOrder" INTEGER, - "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "userId" VARCHAR(100), - CONSTRAINT "fk_createdBy" - FOREIGN KEY("createdBy") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_doneMeetingId" - FOREIGN KEY("doneMeetingId") - REFERENCES "NewMeeting"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_meetingId" - FOREIGN KEY("meetingId") - REFERENCES "NewMeeting"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_discussionId" - FOREIGN KEY("discussionId") - REFERENCES "Discussion"("id") - ON DELETE SET NULL, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE SET NULL - ); - CREATE INDEX IF NOT EXISTS "idx_Task_createdBy" ON "Task"("createdBy"); - CREATE INDEX IF NOT EXISTS "idx_Task_discussionId" ON "Task"("discussionId") WHERE "discussionId" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_Task_integrationHash" ON "Task"("integrationHash") WHERE "integrationHash" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_Task_meetingId" ON "Task"("meetingId") WHERE "meetingId" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_Task_teamId_updatedAt" ON "Task"("teamId", "updatedAt" DESC); - CREATE INDEX IF NOT EXISTS "idx_Task_threadParentId" ON "Task"("threadParentId") WHERE "threadParentId" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_Task_userId" ON "Task"("userId") WHERE "userId" IS NOT NULL; - DROP TRIGGER IF EXISTS "update_Task_updatedAt" ON "Task"; - CREATE TRIGGER "update_Task_updatedAt" BEFORE UPDATE ON "Task" FOR EACH ROW EXECUTE PROCEDURE "set_updatedAt"(); - - END $$; -`.execute(pg) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "Task"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1728595090540_Task-phase2.ts b/packages/server/postgres/migrations/1728595090540_Task-phase2.ts deleted file mode 100644 index e5e0b160b66..00000000000 --- a/packages/server/postgres/migrations/1728595090540_Task-phase2.ts +++ /dev/null @@ -1,170 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('Task') - .indexCreate('updatedAtId', (row: any) => [row('updatedAt'), row('id')]) - .run() - await r.table('Task').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'content', - 'createdAt', - 'createdBy', - 'doneMeetingId', - 'dueDate', - 'integration', - 'integrationHash', - 'meetingId', - 'plaintextContent', - 'sortOrder', - 'status', - 'tags', - 'teamId', - 'discussionId', - 'threadParentId', - 'threadSortOrder', - 'updatedAt', - 'userId' - ] as const - type Task = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - - const insertRow = async (row) => { - try { - await pg - .insertInto('Task') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_teamId') { - console.log('Task has no team, skipping insert', row.id) - return - } - if (e.constraint === 'fk_meetingId') { - console.log('Task has no meeting, skipping insert', row.id) - return - } - if (e.constraint === 'fk_discussionId') { - console.log('Task has no discussionId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_createdBy') { - console.log('Task has no createdBy user, skipping insert', row.id) - return - } - if (e.constraint === 'fk_doneMeetingId') { - console.log('Task has no doneMeetingId user, skipping insert', row.id) - return - } - if (e.constraint === 'fk_userId') { - console.log('Task has no userId user, skipping insert', row.id) - return - } - if (e.message.includes('invalid input value for enum "TaskTagEnum"')) { - console.log('Task has invalid enum, skipping insert', row.id) - return - } - throw e - } - } - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('Task') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as Task[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const { - id, - content, - createdAt, - createdBy, - doneMeetingId, - dueDate, - integration, - integrationHash, - meetingId, - plaintextContent, - sortOrder, - status, - tags, - teamId, - discussionId, - threadParentId, - threadSortOrder, - updatedAt, - userId - } = row as any - return { - id, - content: JSON.stringify(content), - createdAt, - createdBy, - doneMeetingId, - dueDate, - integration: JSON.stringify(integration), - integrationHash, - meetingId, - plaintextContent: plaintextContent.slice(0, 2000), - sortOrder, - status, - tags, - teamId, - discussionId, - threadParentId, - threadSortOrder: threadSortOrder ? Math.round(threadSortOrder) : null, - updatedAt, - userId - } - }) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.updatedAt - curId = lastRow.id - await Promise.all(rowsToInsert.map(async (row) => insertRow(row))) - } -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "Task" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1728596434080_Task-phase2fixup.ts b/packages/server/postgres/migrations/1728596434080_Task-phase2fixup.ts deleted file mode 100644 index e72b6473c82..00000000000 --- a/packages/server/postgres/migrations/1728596434080_Task-phase2fixup.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import getPg from '../getPg' - -export async function up() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await pg - .updateTable('Task') - // coerce the serialized string to jsonb - .set({content: sql`(content #>> '{}')::jsonb`}) - .execute() -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1728596443080_Notification-phase1.ts b/packages/server/postgres/migrations/1728596443080_Notification-phase1.ts deleted file mode 100644 index 11b3d8456e6..00000000000 --- a/packages/server/postgres/migrations/1728596443080_Notification-phase1.ts +++ /dev/null @@ -1,182 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {Client} from 'pg' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' -import getPgConfig from '../getPgConfig' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - await sql` - DO $$ - BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'NotificationStatusEnum') THEN - CREATE TYPE "NotificationStatusEnum" AS ENUM ( - 'UNREAD', - 'CLICKED', - 'READ' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'NotificationTypeEnum') THEN - CREATE TYPE "NotificationTypeEnum" AS ENUM ( - 'DISCUSSION_MENTIONED', - 'KICKED_OUT', - 'MEETING_STAGE_TIME_LIMIT_END', - 'PAYMENT_REJECTED', - 'PROMOTE_TO_BILLING_LEADER', - 'RESPONSE_MENTIONED', - 'RESPONSE_REPLIED', - 'MENTIONED', - 'TASK_INVOLVES', - 'TEAM_ARCHIVED', - 'TEAM_INVITATION', - 'TEAMS_LIMIT_EXCEEDED', - 'TEAMS_LIMIT_REMINDER', - 'PROMPT_TO_JOIN_ORG', - 'REQUEST_TO_JOIN_ORG' - ); - END IF; - IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'TaskInvolvementEnum') THEN - CREATE TYPE "TaskInvolvementEnum" AS ENUM ( - 'ASSIGNEE', - 'MENTIONEE' - ); - END IF; - CREATE TABLE IF NOT EXISTS "Notification" ( - "id" VARCHAR(100) NOT NULL PRIMARY KEY, - "status" "NotificationStatusEnum" NOT NULL DEFAULT 'UNREAD', - "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), - "type" "NotificationTypeEnum" NOT NULL, - "userId" VARCHAR(100) NOT NULL, - -- DISCUSSION_MENTIONED - "meetingId" VARCHAR(100), - "authorId" VARCHAR(100), - "commentId" VARCHAR(100), - "discussionId" VARCHAR(100), - -- KICKED_OUT - "teamId" VARCHAR(100), - "evictorUserId" VARCHAR(100), - -- MENTIONED - "senderName" VARCHAR(100), - "senderPicture" VARCHAR(2056), - "senderUserId" VARCHAR(100), - "meetingName" VARCHAR(100), - "retroReflectionId" VARCHAR(100), - "retroDiscussStageIdx" SMALLINT, - -- PAYMENT_REJECTED - "orgId" VARCHAR(100), - "last4" SMALLINT, - "brand" VARCHAR(50), - -- PROMPT_TO_JOIN_ORG - "activeDomain" VARCHAR(100), - -- REQUEST_TO_JOIN_ORG - "domainJoinRequestId" INTEGER, - "email" "citext", - "name" VARCHAR(100), - "picture" VARCHAR(2056), - "requestCreatedBy" VARCHAR(100), - -- RESPONSE_MENTIONED - "responseId" INTEGER, - -- TASK_INVOLVES - "changeAuthorId" VARCHAR(100), - "involvement" "TaskInvolvementEnum", - "taskId" VARCHAR(100), - -- TEAM_ARCHIVED - "archivorUserId" VARCHAR(100), - -- TEAM_INVITATION - "invitationId" VARCHAR(100), - -- TEAMS_LIMIT_EXCEEDED - "orgName" VARCHAR(100), - "orgPicture" VARCHAR(2056), - -- TEAMS_LIMIT_REMINDER - "scheduledLockAt" TIMESTAMP WITH TIME ZONE, - CONSTRAINT "fk_meetingId" - FOREIGN KEY("meetingId") - REFERENCES "NewMeeting"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_userId" - FOREIGN KEY("userId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_changeAuthorId" - FOREIGN KEY("changeAuthorId") - REFERENCES "TeamMember"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_taskId" - FOREIGN KEY("taskId") - REFERENCES "Task"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_archivorUserId" - FOREIGN KEY("archivorUserId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_orgId" - FOREIGN KEY("orgId") - REFERENCES "Organization"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_evictorUserId" - FOREIGN KEY("evictorUserId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_invitationId" - FOREIGN KEY("invitationId") - REFERENCES "TeamInvitation"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_responseId" - FOREIGN KEY("responseId") - REFERENCES "TeamPromptResponse"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_authorId" - FOREIGN KEY("authorId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_commentId" - FOREIGN KEY("commentId") - REFERENCES "Comment"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_teamId" - FOREIGN KEY("teamId") - REFERENCES "Team"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_discussionId" - FOREIGN KEY("discussionId") - REFERENCES "Discussion"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_senderUserId" - FOREIGN KEY("senderUserId") - REFERENCES "User"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_retroReflectionId" - FOREIGN KEY("retroReflectionId") - REFERENCES "RetroReflection"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_domainJoinRequestId" - FOREIGN KEY("domainJoinRequestId") - REFERENCES "DomainJoinRequest"("id") - ON DELETE CASCADE, - CONSTRAINT "fk_requestCreatedBy" - FOREIGN KEY("requestCreatedBy") - REFERENCES "User"("id") - ON DELETE CASCADE - ); - CREATE INDEX IF NOT EXISTS "idx_Notification_userId" ON "Notification"("userId"); - CREATE INDEX IF NOT EXISTS "idx_Notification_createdAt" ON "Notification"("createdAt"); - CREATE INDEX IF NOT EXISTS "idx_Notification_teamId" ON "Notification"("teamId") WHERE "teamId" IS NOT NULL; - CREATE INDEX IF NOT EXISTS "idx_Notification_orgId" ON "Notification"("orgId") WHERE "orgId" IS NOT NULL; - END $$; -`.execute(pg) -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DROP TABLE IF EXISTS "Notification"; - ` /* Do undo magic */) - await client.end() -} diff --git a/packages/server/postgres/migrations/1729098152007_Notification-phase2.ts b/packages/server/postgres/migrations/1729098152007_Notification-phase2.ts deleted file mode 100644 index 0332d5e7361..00000000000 --- a/packages/server/postgres/migrations/1729098152007_Notification-phase2.ts +++ /dev/null @@ -1,193 +0,0 @@ -import {Kysely, PostgresDialect, sql} from 'kysely' -import {r} from 'rethinkdb-ts' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - try { - console.log('Adding index') - await r - .table('Notification') - .indexCreate('updatedAtId', (row: any) => [row('createdAt'), row('id')]) - .run() - await r.table('Notification').indexWait().run() - } catch { - // index already exists - } - - console.log('Adding index complete') - - const MAX_PG_PARAMS = 65545 - const PG_COLS = [ - 'id', - 'status', - 'createdAt', - 'type', - 'userId', - 'meetingId', - 'authorId', - 'commentId', - 'discussionId', - 'teamId', - 'evictorUserId', - 'senderName', - 'senderPicture', - 'senderUserId', - 'meetingName', - 'retroReflectionId', - 'retroDiscussStageIdx', - 'orgId', - 'last4', - 'brand', - 'activeDomain', - 'domainJoinRequestId', - 'email', - 'name', - 'picture', - 'requestCreatedBy', - 'responseId', - 'changeAuthorId', - 'involvement', - 'taskId', - 'archivorUserId', - 'invitationId', - 'orgName', - 'orgPicture', - 'scheduledLockAt' - ] as const - type Notification = { - [K in (typeof PG_COLS)[number]]: any - } - const BATCH_SIZE = Math.trunc(MAX_PG_PARAMS / PG_COLS.length) - - let curUpdatedAt = r.minval - let curId = r.minval - - const insertRow = async (row) => { - if (!row.type) { - console.log('Notification has no type, skipping insert', row.id) - return - } - try { - await pg - .insertInto('Notification') - .values(row) - .onConflict((oc) => oc.doNothing()) - .execute() - } catch (e) { - if (e.constraint === 'fk_meetingId') { - console.log('Notification has no meeting, skipping insert', row.id) - return - } - if (e.constraint === 'fk_userId') { - console.log('Notification has no user, skipping insert', row.id) - return - } - if (e.constraint === 'fk_changeAuthorId') { - console.log('Notification has no fk_changeAuthorId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_taskId') { - console.log('Notification has no fk_taskId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_archivorUserId') { - console.log('Notification has no fk_archivorUserId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_orgId') { - console.log('Notification has no fk_orgId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_evictorUserId') { - console.log('Notification has no fk_evictorUserId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_invitationId') { - console.log('Notification has no fk_invitationId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_responseId') { - console.log('Notification has no fk_responseId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_authorId') { - console.log('Notification has no fk_authorId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_commentId') { - console.log('Notification has no fk_commentId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_teamId') { - console.log('Notification has no fk_teamId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_discussionId') { - console.log('Notification has no fk_discussionId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_senderUserId') { - console.log('Notification has no fk_senderUserId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_retroReflectionId') { - console.log('Notification has no fk_retroReflectionId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_domainJoinRequestId') { - console.log('Notification has no fk_domainJoinRequestId, skipping insert', row.id) - return - } - if (e.constraint === 'fk_requestCreatedBy') { - console.log('Notification has no fk_requestCreatedBy, skipping insert', row.id) - return - } - throw e - } - } - for (let i = 0; i < 1e6; i++) { - console.log('inserting row', i * BATCH_SIZE, String(curUpdatedAt), String(curId)) - const rawRowsToInsert = (await r - .table('Notification') - .between([curUpdatedAt, curId], [r.maxval, r.maxval], { - index: 'updatedAtId', - leftBound: 'open', - rightBound: 'closed' - }) - .orderBy({index: 'updatedAtId'}) - .limit(BATCH_SIZE) - .pluck(...PG_COLS) - .run()) as Notification[] - - const rowsToInsert = rawRowsToInsert.map((row) => { - const {responseId, ...rest} = row as any - return { - ...rest, - responseId: responseId ? Number(responseId.split(':')[1]) : null - } - }) - - if (rowsToInsert.length === 0) break - const lastRow = rowsToInsert[rowsToInsert.length - 1] - curUpdatedAt = lastRow.createdAt - curId = lastRow.id - await Promise.all(rowsToInsert.map(async (row) => insertRow(row))) - } -} - -export async function down() { - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - await sql`TRUNCATE TABLE "Notification" CASCADE`.execute(pg) -} diff --git a/packages/server/postgres/migrations/1729110751093_pgSchemaFixups.ts b/packages/server/postgres/migrations/1729110751093_pgSchemaFixups.ts deleted file mode 100644 index f7ae4b9f392..00000000000 --- a/packages/server/postgres/migrations/1729110751093_pgSchemaFixups.ts +++ /dev/null @@ -1,85 +0,0 @@ -import {Kysely, PostgresDialect} from 'kysely' -import connectRethinkDB from '../../database/connectRethinkDB' -import getPg from '../getPg' - -export async function up() { - await connectRethinkDB() - const pg = new Kysely({ - dialect: new PostgresDialect({ - pool: getPg() - }) - }) - - const removeRelationalIntegrityViolators = async (table: string, fk: string, fkTable: string) => { - console.log('deleting bad rows', table, fk, fkTable) - const res = await pg - .deleteFrom(table) - .where(fk, 'is not', null) - .where(({not, exists, selectFrom}) => - not( - exists(selectFrom(fkTable).select('id').whereRef(`${table}.${fk}`, '=', `${fkTable}.id`)) - ) - ) - .executeTakeFirst() - console.log(`Deleted ${res.numDeletedRows} rows from ${table} with bad ${fk}`) - } - - const addFKConstraint = async (table: string, fk: string, fkTable: string) => { - console.log('adding constraint', table, fk, fkTable) - try { - await pg.schema - .alterTable(table) - .addForeignKeyConstraint(`fk_${fk}`, [fk], fkTable, ['id']) - .onDelete('cascade') - .execute() - } catch (e) { - console.log('error adding constraint', table, fk, fkTable, e) - return - } - console.log('added constraint', table, fk, fkTable) - } - - const violations = [ - {table: 'AtlassianAuth', fk: 'userId', fkTable: 'User'}, - {table: 'AtlassianAuth', fk: 'teamId', fkTable: 'Team'}, - {table: 'AzureDevOpsDimensionFieldMap', fk: 'teamId', fkTable: 'Team'}, - {table: 'Discussion', fk: 'teamId', fkTable: 'Team'}, - {table: 'Discussion', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'GitHubAuth', fk: 'userId', fkTable: 'User'}, - {table: 'GitHubAuth', fk: 'teamId', fkTable: 'Team'}, - {table: 'GitHubDimensionFieldMap', fk: 'teamId', fkTable: 'Team'}, - {table: 'GitLabDimensionFieldMap', fk: 'teamId', fkTable: 'Team'}, - {table: 'Insight', fk: 'teamId', fkTable: 'Team'}, - {table: 'IntegrationProvider', fk: 'orgId', fkTable: 'Organization'}, - {table: 'IntegrationSearchQuery', fk: 'teamId', fkTable: 'Team'}, - {table: 'JiraDimensionFieldMap', fk: 'teamId', fkTable: 'Team'}, - {table: 'JiraServerDimensionFieldMap', fk: 'teamId', fkTable: 'Team'}, - {table: 'OrganizationApprovedDomain', fk: 'orgId', fkTable: 'Organization'}, - {table: 'OrganizationUserAudit', fk: 'orgId', fkTable: 'Organization'}, - {table: 'OrganizationUserAudit', fk: 'userId', fkTable: 'User'}, - {table: 'Poll', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'RetroReflection', fk: 'promptId', fkTable: 'ReflectPrompt'}, - {table: 'RetroReflection', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'RetroReflectionGroup', fk: 'promptId', fkTable: 'ReflectPrompt'}, - {table: 'RetroReflectionGroup', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'ScheduledJob', fk: 'orgId', fkTable: 'Organization'}, - {table: 'ScheduledJob', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'TaskEstimate', fk: 'taskId', fkTable: 'Task'}, - {table: 'TaskEstimate', fk: 'userId', fkTable: 'User'}, - {table: 'TaskEstimate', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'TaskEstimate', fk: 'discussionId', fkTable: 'Discussion'}, - {table: 'Team', fk: 'orgId', fkTable: 'Organization'}, - {table: 'TeamPromptResponse', fk: 'meetingId', fkTable: 'NewMeeting'}, - {table: 'TimelineEvent', fk: 'orgId', fkTable: 'Organization'}, - {table: 'TimelineEvent', fk: 'meetingId', fkTable: 'NewMeeting'} - ] - for (let i = 0; i < violations.length; i++) { - const {table, fk, fkTable} = violations[i] - await removeRelationalIntegrityViolators(table, fk, fkTable) - await addFKConstraint(table, fk, fkTable) - } -} - -export async function down() { - // noop -} diff --git a/packages/server/postgres/migrations/1729269619262_addSharedSecretIntegrationProvider.ts b/packages/server/postgres/migrations/1729269619262_addSharedSecretIntegrationProvider.ts deleted file mode 100644 index 82f7473367e..00000000000 --- a/packages/server/postgres/migrations/1729269619262_addSharedSecretIntegrationProvider.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TYPE "IntegrationProviderAuthStrategyEnum" ADD VALUE IF NOT EXISTS 'sharedSecret'; - ALTER TABLE "IntegrationProvider" - ADD COLUMN IF NOT EXISTS "sharedSecret" VARCHAR(255); - - ALTER TABLE "TeamMemberIntegrationAuth" - ADD COLUMN IF NOT EXISTS "channel" VARCHAR(255); - END $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - DELETE FROM "IntegrationProvider" WHERE "authStrategy" = 'sharedSecret'; - ALTER TYPE "IntegrationProviderAuthStrategyEnum" RENAME TO "IntegrationProviderAuthStrategyEnumA_delete"; - - CREATE TYPE "IntegrationProviderAuthStrategyEnum" AS ENUM ( - 'pat', - 'oauth2', - 'webhook', - 'oauth1' - ); - - ALTER TABLE "IntegrationProvider" - DROP COLUMN IF EXISTS "sharedSecret", - ALTER COLUMN "authStrategy" TYPE "IntegrationProviderAuthStrategyEnum" USING "authStrategy"::text::"IntegrationProviderAuthStrategyEnum"; - - DROP TYPE "IntegrationProviderAuthStrategyEnumA_delete"; - - ALTER TABLE "TeamMemberIntegrationAuth" - DROP COLUMN IF EXISTS "channel"; - END $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1729696433080_addMeetingsCountToInsight.ts b/packages/server/postgres/migrations/1729696433080_addMeetingsCountToInsight.ts deleted file mode 100644 index fc3dadea186..00000000000 --- a/packages/server/postgres/migrations/1729696433080_addMeetingsCountToInsight.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Insight" - ADD COLUMN IF NOT EXISTS "meetingsCount" INTEGER NOT NULL DEFAULT 0; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - ALTER TABLE "Insight" - DROP COLUMN IF EXISTS "meetingsCount"; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/1729899017181_removeTeamInsights.ts b/packages/server/postgres/migrations/1729899017181_removeTeamInsights.ts deleted file mode 100644 index e2a90737e3a..00000000000 --- a/packages/server/postgres/migrations/1729899017181_removeTeamInsights.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {Client} from 'pg' -import getPgConfig from '../getPgConfig' - -export async function up() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - DROP COLUMN IF EXISTS "insightsUpdatedAt", - DROP COLUMN IF EXISTS "mostUsedEmojis", - DROP COLUMN IF EXISTS "topRetroTemplates", - DROP COLUMN IF EXISTS "meetingEngagement"; - END - $$; - `) - await client.end() -} - -export async function down() { - const client = new Client(getPgConfig()) - await client.connect() - await client.query(` - DO $$ - BEGIN - ALTER TABLE "Team" - ADD COLUMN IF NOT EXISTS "insightsUpdatedAt" TIMESTAMP WITH TIME ZONE, - ADD COLUMN IF NOT EXISTS "mostUsedEmojis" JSONB, - ADD COLUMN IF NOT EXISTS "topRetroTemplates" JSONB, - ADD COLUMN IF NOT EXISTS "meetingEngagement" JSONB; - END - $$; - `) - await client.end() -} diff --git a/packages/server/postgres/migrations/2024-10-21T21:21:21.212Z_init.ts b/packages/server/postgres/migrations/2024-10-21T21:21:21.212Z_init.ts new file mode 100644 index 00000000000..709dbad61ee --- /dev/null +++ b/packages/server/postgres/migrations/2024-10-21T21:21:21.212Z_init.ts @@ -0,0 +1,11552 @@ +import {sql, type Kysely} from 'kysely' +export async function up(db: Kysely): Promise { + const hasUserTable = await sql<{exists: boolean}>` + SELECT EXISTS ( + SELECT 1 + FROM pg_tables + WHERE schemaname = 'public' + AND tablename = 'User' + );`.execute(db) + if (hasUserTable.rows[0].exists) { + // if the DB already exists, just remove the old migrations table + await db.schema.dropTable('PgMigrations').ifExists().execute() + return + } + // If the DB is brand new, initialize it with tables & seed data + await sql`-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 16.2 (Debian 16.2-1.pgdg120+2) +-- Dumped by pg_dump version 16.3 + +-- Started on 2024-10-21 22:59:16 UTC + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- TOC entry 2 (class 3079 OID 2493683) +-- Name: citext; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public; + + +-- +-- TOC entry 1008 (class 1247 OID 2493680) +-- Name: AuthTokenRole; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."AuthTokenRole" AS ENUM ( + 'su' +); + + +-- +-- TOC entry 1032 (class 1247 OID 2493869) +-- Name: ChangeSourceEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."ChangeSourceEnum" AS ENUM ( + 'meeting', + 'task', + 'external' +); + + +-- +-- TOC entry 1155 (class 1247 OID 2494948) +-- Name: CreditCard; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."CreditCard" AS ( + brand text, + expiry text, + last4 smallint +); + + +-- +-- TOC entry 1023 (class 1247 OID 2493836) +-- Name: DiscussionTopicTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."DiscussionTopicTypeEnum" AS ENUM ( + 'agendaItem', + 'reflectionGroup', + 'task', + 'githubIssue', + 'jiraIssue', + 'teamPromptResponse' +); + + +-- +-- TOC entry 1140 (class 1247 OID 2494400) +-- Name: EmbeddingsJobStateEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."EmbeddingsJobStateEnum" AS ENUM ( + 'queued', + 'running', + 'failed' +); + + +-- +-- TOC entry 1119 (class 1247 OID 2494396) +-- Name: EmbeddingsObjectTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."EmbeddingsObjectTypeEnum" AS ENUM ( + 'retrospectiveDiscussionTopic', + 'meetingTemplate' +); + + +-- +-- TOC entry 1230 (class 1247 OID 2495445) +-- Name: FeatureFlagScope; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."FeatureFlagScope" AS ENUM ( + 'User', + 'Team', + 'Organization' +); + + +-- +-- TOC entry 1143 (class 1247 OID 2494876) +-- Name: GoogleAnalyzedEntity; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."GoogleAnalyzedEntity" AS ( + name text, + salience real, + lemma text +); + + +-- +-- TOC entry 1137 (class 1247 OID 2494475) +-- Name: ISO6391Enum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."ISO6391Enum" AS ENUM ( + 'aa', + 'ab', + 'af', + 'ak', + 'am', + 'ar', + 'an', + 'as', + 'av', + 'ae', + 'ay', + 'az', + 'ba', + 'bm', + 'be', + 'bn', + 'bi', + 'bo', + 'bs', + 'br', + 'bg', + 'ca', + 'cs', + 'ch', + 'ce', + 'cu', + 'cv', + 'kw', + 'co', + 'cr', + 'cy', + 'da', + 'de', + 'dv', + 'dz', + 'el', + 'en', + 'eo', + 'et', + 'eu', + 'ee', + 'fo', + 'fa', + 'fj', + 'fi', + 'fr', + 'fy', + 'ff', + 'gd', + 'ga', + 'gl', + 'gv', + 'gn', + 'gu', + 'ht', + 'ha', + 'sh', + 'he', + 'hz', + 'hi', + 'ho', + 'hr', + 'hu', + 'hy', + 'ig', + 'io', + 'ii', + 'iu', + 'ie', + 'ia', + 'id', + 'ik', + 'is', + 'it', + 'jv', + 'ja', + 'kl', + 'kn', + 'ks', + 'ka', + 'kr', + 'kk', + 'km', + 'ki', + 'rw', + 'ky', + 'kv', + 'kg', + 'ko', + 'kj', + 'ku', + 'lo', + 'la', + 'lv', + 'li', + 'ln', + 'lt', + 'lb', + 'lu', + 'lg', + 'mh', + 'ml', + 'mr', + 'mk', + 'mg', + 'mt', + 'mn', + 'mi', + 'ms', + 'my', + 'na', + 'nv', + 'nr', + 'nd', + 'ng', + 'ne', + 'nl', + 'nn', + 'nb', + 'no', + 'ny', + 'oc', + 'oj', + 'or', + 'om', + 'os', + 'pa', + 'pi', + 'pl', + 'pt', + 'ps', + 'qu', + 'rm', + 'ro', + 'rn', + 'ru', + 'sg', + 'sa', + 'si', + 'sk', + 'sl', + 'se', + 'sm', + 'sn', + 'sd', + 'so', + 'st', + 'es', + 'sq', + 'sc', + 'sr', + 'ss', + 'su', + 'sw', + 'sv', + 'ty', + 'ta', + 'tt', + 'te', + 'tg', + 'tl', + 'th', + 'ti', + 'to', + 'tn', + 'ts', + 'tk', + 'tr', + 'tw', + 'ug', + 'uk', + 'ur', + 'uz', + 've', + 'vi', + 'vo', + 'wa', + 'wo', + 'xh', + 'yi', + 'yo', + 'za', + 'zh', + 'zu' +); + + +-- +-- TOC entry 1053 (class 1247 OID 2493972) +-- Name: IntegrationProviderAuthStrategyEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."IntegrationProviderAuthStrategyEnum" AS ENUM ( + 'pat', + 'oauth2', + 'webhook', + 'oauth1', + 'sharedSecret' +); + + +-- +-- TOC entry 1056 (class 1247 OID 2493980) +-- Name: IntegrationProviderScopeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."IntegrationProviderScopeEnum" AS ENUM ( + 'global', + 'org', + 'team' +); + + +-- +-- TOC entry 1050 (class 1247 OID 2493966) +-- Name: IntegrationProviderServiceEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."IntegrationProviderServiceEnum" AS ENUM ( + 'gitlab', + 'mattermost', + 'jiraServer', + 'azureDevOps', + 'msTeams', + 'gcal' +); + + +-- +-- TOC entry 1017 (class 1247 OID 2493809) +-- Name: MeetingTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."MeetingTypeEnum" AS ENUM ( + 'action', + 'retrospective', + 'poker', + 'teamPrompt' +); + + +-- +-- TOC entry 1197 (class 1247 OID 2495166) +-- Name: NewMeetingPhaseTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."NewMeetingPhaseTypeEnum" AS ENUM ( + 'ESTIMATE', + 'SCOPE', + 'SUMMARY', + 'agendaitems', + 'checkin', + 'TEAM_HEALTH', + 'discuss', + 'firstcall', + 'group', + 'lastcall', + 'lobby', + 'reflect', + 'updates', + 'vote', + 'RESPONSES' +); + + +-- +-- TOC entry 1260 (class 1247 OID 2495658) +-- Name: NotificationStatusEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."NotificationStatusEnum" AS ENUM ( + 'UNREAD', + 'CLICKED', + 'READ' +); + + +-- +-- TOC entry 1263 (class 1247 OID 2495666) +-- Name: NotificationTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."NotificationTypeEnum" AS ENUM ( + 'DISCUSSION_MENTIONED', + 'KICKED_OUT', + 'MEETING_STAGE_TIME_LIMIT_END', + 'PAYMENT_REJECTED', + 'PROMOTE_TO_BILLING_LEADER', + 'RESPONSE_MENTIONED', + 'RESPONSE_REPLIED', + 'MENTIONED', + 'TASK_INVOLVES', + 'TEAM_ARCHIVED', + 'TEAM_INVITATION', + 'TEAMS_LIMIT_EXCEEDED', + 'TEAMS_LIMIT_REMINDER', + 'PROMPT_TO_JOIN_ORG', + 'REQUEST_TO_JOIN_ORG' +); + + +-- +-- TOC entry 1161 (class 1247 OID 2494967) +-- Name: OrgUserRoleEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."OrgUserRoleEnum" AS ENUM ( + 'BILLING_LEADER', + 'ORG_ADMIN' +); + + +-- +-- TOC entry 990 (class 1247 OID 2493632) +-- Name: OrganizationUserAuditEventTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."OrganizationUserAuditEventTypeEnum" AS ENUM ( + 'added', + 'activated', + 'inactivated', + 'removed' +); + + +-- +-- TOC entry 1065 (class 1247 OID 2494041) +-- Name: Reactji; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."Reactji" AS ( + id text, + "userId" text +); + + +-- +-- TOC entry 1131 (class 1247 OID 2494455) +-- Name: ScheduledJobTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."ScheduledJobTypeEnum" AS ENUM ( + 'MEETING_STAGE_TIME_LIMIT_END', + 'LOCK_ORGANIZATION', + 'WARN_ORGANIZATION' +); + + +-- +-- TOC entry 1092 (class 1247 OID 2494195) +-- Name: SharingScopeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."SharingScopeEnum" AS ENUM ( + 'USER', + 'TEAM', + 'ORGANIZATION', + 'PUBLIC' +); + + +-- +-- TOC entry 1209 (class 1247 OID 2495269) +-- Name: SlackNotificationEventEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."SlackNotificationEventEnum" AS ENUM ( + 'meetingStart', + 'meetingEnd', + 'MEETING_STAGE_TIME_LIMIT_END', + 'MEETING_STAGE_TIME_LIMIT_START', + 'TOPIC_SHARED', + 'STANDUP_RESPONSE_SUBMITTED' +); + + +-- +-- TOC entry 1188 (class 1247 OID 2495112) +-- Name: SuggestedActionTypeEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."SuggestedActionTypeEnum" AS ENUM ( + 'inviteYourTeam', + 'tryTheDemo', + 'createNewTeam', + 'tryRetroMeeting', + 'tryActionMeeting' +); + + +-- +-- TOC entry 1266 (class 1247 OID 2495698) +-- Name: TaskInvolvementEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."TaskInvolvementEnum" AS ENUM ( + 'ASSIGNEE', + 'MENTIONEE' +); + + +-- +-- TOC entry 1251 (class 1247 OID 2495592) +-- Name: TaskStatusEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."TaskStatusEnum" AS ENUM ( + 'active', + 'stuck', + 'done', + 'future' +); + + +-- +-- TOC entry 1254 (class 1247 OID 2495602) +-- Name: TaskTagEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."TaskTagEnum" AS ENUM ( + 'private', + 'archived' +); + + +-- +-- TOC entry 1167 (class 1247 OID 2494992) +-- Name: TeamDrawerEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."TeamDrawerEnum" AS ENUM ( + 'agenda', + 'manageTeam' +); + + +-- +-- TOC entry 1005 (class 1247 OID 2493673) +-- Name: TierEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."TierEnum" AS ENUM ( + 'starter', + 'team', + 'enterprise' +); + + +-- +-- TOC entry 1149 (class 1247 OID 2494911) +-- Name: TimelineEventEnum; Type: TYPE; Schema: public; Owner: - +-- + +CREATE TYPE public."TimelineEventEnum" AS ENUM ( + 'TEAM_PROMPT_COMPLETE', + 'POKER_COMPLETE', + 'actionComplete', + 'createdTeam', + 'joinedParabol', + 'retroComplete' +); + + +-- +-- TOC entry 372 (class 1255 OID 2493806) +-- Name: arr_append_uniq(anyarray, anyelement); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.arr_append_uniq(anyarray, anyelement) RETURNS anyarray + LANGUAGE sql IMMUTABLE + AS $_$SELECT CASE WHEN array_position($1, $2) iS NULL THEN $1 || $2 ELSE $1 END;$_$; + + +-- +-- TOC entry 360 (class 1255 OID 2493807) +-- Name: arr_diff(anyarray, anyarray); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.arr_diff(arr1 anyarray, arr2 anyarray) RETURNS anyarray + LANGUAGE sql IMMUTABLE + AS $$ + SELECT COALESCE(array_agg(el), '{}') + FROM UNNEST(arr1) el + WHERE el != all(arr2) + $$; + + +-- +-- TOC entry 332 (class 1255 OID 2493830) +-- Name: arr_merge(anyarray, anyarray); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.arr_merge(a1 anyarray, a2 anyarray) RETURNS anyarray + LANGUAGE sql STRICT + AS $_$ + SELECT ARRAY_AGG(a ORDER BY a) FROM ( + SELECT DISTINCT UNNEST($1 || $2) AS a + ) s; + $_$; + + +-- +-- TOC entry 341 (class 1255 OID 2494907) +-- Name: getEmbedderPriority(integer); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public."getEmbedderPriority"("maxDelayInDays" integer) RETURNS integer + LANGUAGE plpgsql + AS $$ + BEGIN + RETURN -(2 ^ 31) + FLOOR(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) / 1000) + "maxDelayInDays" * 86400; + END + $$; + + +-- +-- TOC entry 362 (class 1255 OID 2495442) +-- Name: prevent_meeting_overlap(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.prevent_meeting_overlap() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + -- Check if a meeting exists within a 2-second window of the new createdAt + IF EXISTS ( + SELECT 1 FROM "NewMeeting" + WHERE "teamId" = NEW."teamId" + AND "meetingType" = NEW."meetingType" + AND ABS(EXTRACT(EPOCH FROM (NEW."createdAt" - "createdAt"))) < 2 + ) THEN + RAISE EXCEPTION 'Cannot insert meeting. A meeting exists within a 2-second window.'; + END IF; + -- If no conflict, allow the insert + RETURN NEW; + END; + $$; + + +-- +-- TOC entry 353 (class 1255 OID 2495099) +-- Name: set_MeetingTemplate_updatedAt(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public."set_MeetingTemplate_updatedAt"() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + -- Update the updatedAt column in MeetingTemplate + UPDATE "MeetingTemplate" + SET "updatedAt" = CURRENT_TIMESTAMP + WHERE "id" = NEW."templateId"; + RETURN NEW; + END; + $$; + + +-- +-- TOC entry 363 (class 1255 OID 2495097) +-- Name: set_TemplateDimension_updatedAt(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public."set_TemplateDimension_updatedAt"() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + -- Update the updatedAt column in TemplateDimension + UPDATE "TemplateDimension" + SET "updatedAt" = CURRENT_TIMESTAMP + WHERE "scaleId" = NEW."id"; + RETURN NEW; + END; + $$; + + +-- +-- TOC entry 348 (class 1255 OID 2495059) +-- Name: set_TemplateScale_updatedAt(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public."set_TemplateScale_updatedAt"() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + -- Update the updatedAt column in TemplateScale + UPDATE "TemplateScale" + SET "updatedAt" = CURRENT_TIMESTAMP + WHERE id = NEW."templateScaleId"; + RETURN NEW; + END; + $$; + + +-- +-- TOC entry 365 (class 1255 OID 2493963) +-- Name: set_updatedAt(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public."set_updatedAt"() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + NEW."updatedAt" = now(); + RETURN NEW; + END + $$; + + +-- +-- TOC entry 342 (class 1255 OID 2494908) +-- Name: updateEmbedding(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public."updateEmbedding"() RETURNS trigger + LANGUAGE plpgsql + AS $$ + DECLARE + "metadataId" INTEGER; + BEGIN + BEGIN + SELECT id FROM "EmbeddingsMetadata" WHERE "objectType" = 'meetingTemplate' AND "refId" = NEW.id INTO STRICT "metadataId"; + EXCEPTION + WHEN NO_DATA_FOUND THEN + INSERT INTO "EmbeddingsMetadata" ("objectType", "refId", "teamId", "refUpdatedAt") VALUES ('meetingTemplate', NEW.id, NEW."teamId", NEW."updatedAt") RETURNING id INTO "metadataId"; + END; + INSERT INTO "EmbeddingsJobQueue" ("embeddingsMetadataId", "jobType", "priority", "model") VALUES ("metadataId", 'embed:start', "getEmbedderPriority"(1), 'Embeddings_ember_1') ON CONFLICT DO NOTHING; + RETURN NEW; + END + $$; + + +-- +-- TOC entry 292 (class 1259 OID 2495217) +-- Name: AgendaItem; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."AgendaItem" ( + id character varying(100) NOT NULL, + content character varying(64) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + "isComplete" boolean DEFAULT false NOT NULL, + "sortOrder" character varying(64) NOT NULL COLLATE pg_catalog."C", + "teamId" character varying(100) NOT NULL, + "teamMemberId" character varying(100) NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "meetingId" character varying(100), + pinned boolean DEFAULT false NOT NULL, + "pinnedParentId" character varying(100) +); + + +-- +-- TOC entry 226 (class 1259 OID 2493855) +-- Name: AtlassianAuth; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."AtlassianAuth" ( + "accessToken" character varying(2600) NOT NULL, + "refreshToken" character varying(2600) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + "jiraSearchQueries" jsonb[] DEFAULT '{}'::jsonb[] NOT NULL, + "cloudIds" character varying(120)[] DEFAULT '{}'::character varying[] NOT NULL, + scope character varying(240) NOT NULL, + "accountId" character varying(120) NOT NULL, + "teamId" character varying(120) NOT NULL, + "userId" character varying(120) NOT NULL +); + + +-- +-- TOC entry 246 (class 1259 OID 2494075) +-- Name: AzureDevOpsDimensionFieldMap; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."AzureDevOpsDimensionFieldMap" ( + id integer NOT NULL, + "teamId" character varying(120) NOT NULL, + "dimensionName" character varying(120) NOT NULL, + "fieldName" character varying(140) NOT NULL, + "fieldId" character varying(100) NOT NULL, + "instanceId" character varying(100) NOT NULL, + "fieldType" character varying(100) NOT NULL, + "projectKey" character varying(100) NOT NULL, + "workItemType" character varying(255) NOT NULL +); + + +-- +-- TOC entry 245 (class 1259 OID 2494074) +-- Name: AzureDevOpsDimensionFieldMap_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."AzureDevOpsDimensionFieldMap_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4519 (class 0 OID 0) +-- Dependencies: 245 +-- Name: AzureDevOpsDimensionFieldMap_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."AzureDevOpsDimensionFieldMap_id_seq" OWNED BY public."AzureDevOpsDimensionFieldMap".id; + + +-- +-- TOC entry 295 (class 1259 OID 2495300) +-- Name: Comment; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Comment" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + "isAnonymous" boolean DEFAULT false NOT NULL, + "threadParentId" character varying(100), + reactjis public."Reactji"[] DEFAULT ARRAY[]::public."Reactji"[] NOT NULL, + content jsonb NOT NULL, + "createdBy" character varying(100), + "plaintextContent" character varying(2000) NOT NULL, + "discussionId" character varying(100) NOT NULL, + "threadSortOrder" integer NOT NULL +); + + +-- +-- TOC entry 225 (class 1259 OID 2493847) +-- Name: Discussion; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Discussion" ( + id character varying(50) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "teamId" character varying(100) NOT NULL, + "meetingId" character varying(100) NOT NULL, + "discussionTopicId" character varying(100) NOT NULL, + "discussionTopicType" public."DiscussionTopicTypeEnum" NOT NULL, + summary character varying(2000) +); + + +-- +-- TOC entry 260 (class 1259 OID 2494261) +-- Name: DomainJoinRequest; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."DomainJoinRequest" ( + id integer NOT NULL, + "createdBy" character varying(100) NOT NULL, + domain character varying(100) NOT NULL, + "expiresAt" timestamp with time zone, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + CONSTRAINT "DomainJoinRequest_domain_check" CHECK ((lower((domain)::text) = (domain)::text)) +); + + +-- +-- TOC entry 259 (class 1259 OID 2494260) +-- Name: DomainJoinRequest_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."DomainJoinRequest_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4520 (class 0 OID 0) +-- Dependencies: 259 +-- Name: DomainJoinRequest_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."DomainJoinRequest_id_seq" OWNED BY public."DomainJoinRequest".id; + + +-- +-- TOC entry 287 (class 1259 OID 2495102) +-- Name: EmailVerification; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."EmailVerification" ( + id integer NOT NULL, + email public.citext NOT NULL, + expiration timestamp with time zone NOT NULL, + token character varying(100) NOT NULL, + "hashedPassword" character varying(100), + "invitationToken" character varying(100), + "pseudoId" character varying(100) +); + + +-- +-- TOC entry 286 (class 1259 OID 2495101) +-- Name: EmailVerification_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."EmailVerification" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."EmailVerification_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 269 (class 1259 OID 2494427) +-- Name: EmbeddingsJobQueue; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."EmbeddingsJobQueue" ( + id integer NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + state public."EmbeddingsJobStateEnum" DEFAULT 'queued'::public."EmbeddingsJobStateEnum" NOT NULL, + "stateMessage" text, + "retryAfter" timestamp with time zone, + "retryCount" smallint DEFAULT 0 NOT NULL, + "startAt" timestamp with time zone, + priority integer DEFAULT 50 NOT NULL, + "jobData" jsonb DEFAULT '{}'::jsonb NOT NULL, + "jobType" character varying(255) NOT NULL, + model character varying(255), + "embeddingsMetadataId" integer +); + + +-- +-- TOC entry 268 (class 1259 OID 2494426) +-- Name: EmbeddingsJobQueue_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."EmbeddingsJobQueue_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4521 (class 0 OID 0) +-- Dependencies: 268 +-- Name: EmbeddingsJobQueue_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."EmbeddingsJobQueue_id_seq" OWNED BY public."EmbeddingsJobQueue".id; + + +-- +-- TOC entry 267 (class 1259 OID 2494408) +-- Name: EmbeddingsMetadata; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."EmbeddingsMetadata" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "objectType" public."EmbeddingsObjectTypeEnum" NOT NULL, + "refId" character varying(100) NOT NULL, + "refUpdatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "teamId" character varying(100) NOT NULL, + "fullText" text, + language public."ISO6391Enum" +); + + +-- +-- TOC entry 266 (class 1259 OID 2494407) +-- Name: EmbeddingsMetadata_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."EmbeddingsMetadata_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4522 (class 0 OID 0) +-- Dependencies: 266 +-- Name: EmbeddingsMetadata_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."EmbeddingsMetadata_id_seq" OWNED BY public."EmbeddingsMetadata".id; + + +-- +-- TOC entry 271 (class 1259 OID 2494444) +-- Name: FailedAuthRequest; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."FailedAuthRequest" ( + id integer NOT NULL, + email public.citext NOT NULL, + ip inet NOT NULL, + "time" timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- TOC entry 270 (class 1259 OID 2494443) +-- Name: FailedAuthRequest_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."FailedAuthRequest" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."FailedAuthRequest_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 302 (class 1259 OID 2495451) +-- Name: FeatureFlag; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."FeatureFlag" ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + "featureName" character varying(255) NOT NULL, + scope public."FeatureFlagScope" NOT NULL, + description text, + "expiresAt" timestamp with time zone NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +-- +-- TOC entry 303 (class 1259 OID 2495463) +-- Name: FeatureFlagOwner; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."FeatureFlagOwner" ( + "featureFlagId" uuid NOT NULL, + "userId" character varying(255), + "teamId" character varying(255), + "orgId" character varying(255), + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + CONSTRAINT check_feature_flag_owner_exclusivity CHECK (((("userId" IS NOT NULL) AND ("teamId" IS NULL) AND ("orgId" IS NULL)) OR (("userId" IS NULL) AND ("teamId" IS NOT NULL) AND ("orgId" IS NULL)) OR (("userId" IS NULL) AND ("teamId" IS NULL) AND ("orgId" IS NOT NULL)))) +); + + +-- +-- TOC entry 265 (class 1259 OID 2494351) +-- Name: FreemailDomain; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."FreemailDomain" ( + domain character varying(255) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +-- +-- TOC entry 222 (class 1259 OID 2493664) +-- Name: GitHubAuth; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."GitHubAuth" ( + "accessToken" character varying(40) NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + login character varying(200) NOT NULL, + "teamId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "githubSearchQueries" jsonb[] DEFAULT '{}'::jsonb[] NOT NULL, + scope character varying(250) NOT NULL +); + + +-- +-- TOC entry 234 (class 1259 OID 2493929) +-- Name: GitHubDimensionFieldMap; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."GitHubDimensionFieldMap" ( + id integer NOT NULL, + "teamId" character varying(120) NOT NULL, + "dimensionName" character varying(120) NOT NULL, + "nameWithOwner" character varying(140) NOT NULL, + "labelTemplate" character varying(100) NOT NULL +); + + +-- +-- TOC entry 233 (class 1259 OID 2493928) +-- Name: GitHubDimensionFieldMap_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."GitHubDimensionFieldMap_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4523 (class 0 OID 0) +-- Dependencies: 233 +-- Name: GitHubDimensionFieldMap_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."GitHubDimensionFieldMap_id_seq" OWNED BY public."GitHubDimensionFieldMap".id; + + +-- +-- TOC entry 244 (class 1259 OID 2494064) +-- Name: GitLabDimensionFieldMap; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."GitLabDimensionFieldMap" ( + id integer NOT NULL, + "teamId" character varying(100) NOT NULL, + "dimensionName" character varying(120) NOT NULL, + "projectId" integer NOT NULL, + "providerId" integer NOT NULL, + "labelTemplate" character varying(100) NOT NULL +); + + +-- +-- TOC entry 243 (class 1259 OID 2494063) +-- Name: GitLabDimensionFieldMap_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."GitLabDimensionFieldMap_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4524 (class 0 OID 0) +-- Dependencies: 243 +-- Name: GitLabDimensionFieldMap_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."GitLabDimensionFieldMap_id_seq" OWNED BY public."GitLabDimensionFieldMap".id; + + +-- +-- TOC entry 290 (class 1259 OID 2495152) +-- Name: Insight; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Insight" ( + id integer NOT NULL, + "teamId" character varying(100) NOT NULL, + "startDateTime" timestamp with time zone NOT NULL, + "endDateTime" timestamp with time zone NOT NULL, + wins text[] NOT NULL, + challenges text[] NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "meetingsCount" integer DEFAULT 0 NOT NULL +); + + +-- +-- TOC entry 289 (class 1259 OID 2495151) +-- Name: Insight_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."Insight_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4525 (class 0 OID 0) +-- Dependencies: 289 +-- Name: Insight_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."Insight_id_seq" OWNED BY public."Insight".id; + + +-- +-- TOC entry 238 (class 1259 OID 2493988) +-- Name: IntegrationProvider; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."IntegrationProvider" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + service public."IntegrationProviderServiceEnum" NOT NULL, + "authStrategy" public."IntegrationProviderAuthStrategyEnum" NOT NULL, + scope public."IntegrationProviderScopeEnum" NOT NULL, + "scopeGlobal" boolean GENERATED ALWAYS AS ( +CASE + WHEN (scope = 'global'::public."IntegrationProviderScopeEnum") THEN true + ELSE false +END) STORED NOT NULL, + "teamId" character varying(100), + "isActive" boolean DEFAULT true NOT NULL, + "clientId" character varying(255), + "clientSecret" character varying(255), + "serverBaseUrl" character varying(255), + "webhookUrl" character varying(255), + "consumerKey" character varying(255), + "consumerSecret" text, + "tenantId" character varying(255), + "orgId" character varying(100), + "sharedSecret" character varying(255), + CONSTRAINT "scope_global_has_neither_teamId_orgId" CHECK (((scope <> 'global'::public."IntegrationProviderScopeEnum") OR (("orgId" IS NULL) AND ("teamId" IS NULL)))), + CONSTRAINT "scope_org_has_only_orgId" CHECK (((scope <> 'org'::public."IntegrationProviderScopeEnum") OR (("orgId" IS NOT NULL) AND ("teamId" IS NULL)))), + CONSTRAINT "scope_team_has_only_teamId" CHECK (((scope <> 'team'::public."IntegrationProviderScopeEnum") OR (("teamId" IS NOT NULL) AND ("orgId" IS NULL)))) +); + + +-- +-- TOC entry 237 (class 1259 OID 2493987) +-- Name: IntegrationProvider_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."IntegrationProvider" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."IntegrationProvider_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 250 (class 1259 OID 2494107) +-- Name: IntegrationSearchQuery; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."IntegrationSearchQuery" ( + id integer NOT NULL, + "userId" character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "providerId" integer, + service public."IntegrationProviderServiceEnum" NOT NULL, + query jsonb DEFAULT '{}'::jsonb NOT NULL, + "lastUsedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +-- +-- TOC entry 249 (class 1259 OID 2494106) +-- Name: IntegrationSearchQuery_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."IntegrationSearchQuery" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."IntegrationSearchQuery_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 256 (class 1259 OID 2494171) +-- Name: JiraDimensionFieldMap; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."JiraDimensionFieldMap" ( + id integer NOT NULL, + "teamId" character varying(120) NOT NULL, + "cloudId" character varying(120) NOT NULL, + "projectKey" character varying(120) NOT NULL, + "issueType" character varying(120) NOT NULL, + "dimensionName" character varying(120) NOT NULL, + "fieldId" character varying(120) NOT NULL, + "fieldName" character varying(120) NOT NULL, + "fieldType" character varying(120) NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +-- +-- TOC entry 255 (class 1259 OID 2494170) +-- Name: JiraDimensionFieldMap_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."JiraDimensionFieldMap_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4526 (class 0 OID 0) +-- Dependencies: 255 +-- Name: JiraDimensionFieldMap_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."JiraDimensionFieldMap_id_seq" OWNED BY public."JiraDimensionFieldMap".id; + + +-- +-- TOC entry 248 (class 1259 OID 2494088) +-- Name: JiraServerDimensionFieldMap; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."JiraServerDimensionFieldMap" ( + id integer NOT NULL, + "providerId" integer NOT NULL, + "teamId" character varying(120) NOT NULL, + "dimensionName" character varying(120) NOT NULL, + "projectId" character varying(120) NOT NULL, + "issueType" character varying(120) NOT NULL, + "fieldId" character varying(120) NOT NULL, + "fieldName" character varying(120) NOT NULL, + "fieldType" character varying(120) NOT NULL +); + + +-- +-- TOC entry 247 (class 1259 OID 2494087) +-- Name: JiraServerDimensionFieldMap_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."JiraServerDimensionFieldMap_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4527 (class 0 OID 0) +-- Dependencies: 247 +-- Name: JiraServerDimensionFieldMap_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."JiraServerDimensionFieldMap_id_seq" OWNED BY public."JiraServerDimensionFieldMap".id; + + +-- +-- TOC entry 305 (class 1259 OID 2495521) +-- Name: MassInvitation; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."MassInvitation" ( + id character(12) NOT NULL, + expiration timestamp with time zone NOT NULL, + "meetingId" character varying(100), + "teamMemberId" character varying(100) NOT NULL +); + + +-- +-- TOC entry 304 (class 1259 OID 2495496) +-- Name: MeetingMember; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."MeetingMember" ( + id character varying(100) NOT NULL, + "meetingType" public."MeetingTypeEnum" NOT NULL, + "meetingId" character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "userId" character varying(100) NOT NULL, + "isSpectating" boolean, + "votesRemaining" smallint +); + + +-- +-- TOC entry 254 (class 1259 OID 2494149) +-- Name: MeetingSeries; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."MeetingSeries" ( + id integer NOT NULL, + "meetingType" public."MeetingTypeEnum" NOT NULL, + title character varying(255) NOT NULL, + "recurrenceRule" character varying(255) NOT NULL, + duration integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "cancelledAt" timestamp with time zone, + "teamId" character varying(100) NOT NULL, + "facilitatorId" character varying(100) NOT NULL, + "gcalSeriesId" character varying(100) +); + + +-- +-- TOC entry 253 (class 1259 OID 2494148) +-- Name: MeetingSeries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."MeetingSeries" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."MeetingSeries_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 291 (class 1259 OID 2495197) +-- Name: MeetingSettings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."MeetingSettings" ( + id character varying(100) NOT NULL, + "phaseTypes" public."NewMeetingPhaseTypeEnum"[] NOT NULL, + "meetingType" public."MeetingTypeEnum" NOT NULL, + "teamId" character varying(100) NOT NULL, + "selectedTemplateId" character varying(100), + "jiraSearchQueries" jsonb, + "maxVotesPerGroup" smallint, + "totalVotes" smallint, + "disableAnonymity" boolean, + "videoMeetingURL" character varying(2056) +); + + +-- +-- TOC entry 257 (class 1259 OID 2494203) +-- Name: MeetingTemplate; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."MeetingTemplate" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + name character varying(250) NOT NULL, + "teamId" character varying(100) NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + scope public."SharingScopeEnum" DEFAULT 'TEAM'::public."SharingScopeEnum" NOT NULL, + "orgId" character varying(100) NOT NULL, + "parentTemplateId" character varying(100), + "lastUsedAt" timestamp with time zone, + type public."MeetingTypeEnum" NOT NULL, + "isStarter" boolean DEFAULT false NOT NULL, + "isFree" boolean DEFAULT false NOT NULL, + "illustrationUrl" character varying(512) NOT NULL, + "hideStartingAt" timestamp with time zone, + "hideEndingAt" timestamp with time zone, + "mainCategory" character varying(100) NOT NULL +); + + +-- +-- TOC entry 258 (class 1259 OID 2494242) +-- Name: MeetingTemplateUserFavorite; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."MeetingTemplateUserFavorite" ( + "userId" character varying(100) NOT NULL, + "templateId" character varying(100) NOT NULL +); + + +-- +-- TOC entry 307 (class 1259 OID 2495539) +-- Name: NewFeature; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."NewFeature" ( + id integer NOT NULL, + "actionButtonCopy" character varying(50) NOT NULL, + "snackbarMessage" character varying(255) NOT NULL, + url character varying(2056) NOT NULL +); + + +-- +-- TOC entry 306 (class 1259 OID 2495538) +-- Name: NewFeature_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."NewFeature" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."NewFeature_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 301 (class 1259 OID 2495399) +-- Name: NewMeeting; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."NewMeeting" ( + id character varying(100) NOT NULL, + "isLegacy" boolean DEFAULT false NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "createdBy" character varying(100), + "endedAt" timestamp with time zone, + "facilitatorStageId" character varying(100) NOT NULL, + "facilitatorUserId" character varying(100), + "meetingCount" integer NOT NULL, + "meetingNumber" integer NOT NULL, + name character varying(100) NOT NULL, + "summarySentAt" timestamp with time zone, + "teamId" character varying(100) NOT NULL, + "meetingType" public."MeetingTypeEnum" NOT NULL, + phases jsonb NOT NULL, + "showConversionModal" boolean DEFAULT false NOT NULL, + "meetingSeriesId" integer, + "scheduledEndTime" timestamp with time zone, + summary character varying(10000), + "sentimentScore" double precision, + "usedReactjis" jsonb, + "slackTs" double precision, + engagement double precision, + "totalVotes" integer, + "maxVotesPerGroup" smallint, + "disableAnonymity" boolean, + "commentCount" integer, + "taskCount" integer, + "agendaItemCount" integer, + "storyCount" integer, + "templateId" character varying(100), + "topicCount" integer, + "reflectionCount" integer, + transcription jsonb, + "recallBotId" character varying(255), + "videoMeetingURL" character varying(2048), + "autogroupReflectionGroups" jsonb, + "resetReflectionGroups" jsonb, + "templateRefId" character varying(25), + "meetingPrompt" character varying(255) +); + + +-- +-- TOC entry 310 (class 1259 OID 2495703) +-- Name: Notification; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Notification" ( + id character varying(100) NOT NULL, + status public."NotificationStatusEnum" DEFAULT 'UNREAD'::public."NotificationStatusEnum" NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + type public."NotificationTypeEnum" NOT NULL, + "userId" character varying(100) NOT NULL, + "meetingId" character varying(100), + "authorId" character varying(100), + "commentId" character varying(100), + "discussionId" character varying(100), + "teamId" character varying(100), + "evictorUserId" character varying(100), + "senderName" character varying(100), + "senderPicture" character varying(2056), + "senderUserId" character varying(100), + "meetingName" character varying(100), + "retroReflectionId" character varying(100), + "retroDiscussStageIdx" smallint, + "orgId" character varying(100), + last4 smallint, + brand character varying(50), + "activeDomain" character varying(100), + "domainJoinRequestId" integer, + email public.citext, + name character varying(100), + picture character varying(2056), + "requestCreatedBy" character varying(100), + "responseId" integer, + "changeAuthorId" character varying(100), + involvement public."TaskInvolvementEnum", + "taskId" character varying(100), + "archivorUserId" character varying(100), + "invitationId" character varying(100), + "orgName" character varying(100), + "orgPicture" character varying(2056), + "scheduledLockAt" timestamp with time zone +); + + +-- +-- TOC entry 278 (class 1259 OID 2494949) +-- Name: Organization; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Organization" ( + id character varying(100) NOT NULL, + "activeDomain" character varying(100), + "isActiveDomainTouched" boolean DEFAULT false NOT NULL, + "creditCard" public."CreditCard", + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + name character varying(100) NOT NULL, + "payLaterClickCount" smallint DEFAULT 0 NOT NULL, + "periodEnd" timestamp with time zone, + "periodStart" timestamp with time zone, + picture character varying(2056), + "showConversionModal" boolean DEFAULT false NOT NULL, + "stripeId" character varying(100), + "stripeSubscriptionId" character varying(100), + "upcomingInvoiceEmailSentAt" timestamp with time zone, + tier public."TierEnum" DEFAULT 'starter'::public."TierEnum" NOT NULL, + "tierLimitExceededAt" timestamp with time zone, + "trialStartDate" timestamp with time zone, + "scheduledLockAt" timestamp with time zone, + "lockedAt" timestamp with time zone, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "featureFlags" text[] DEFAULT '{}'::text[] NOT NULL +); + + +-- +-- TOC entry 252 (class 1259 OID 2494132) +-- Name: OrganizationApprovedDomain; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."OrganizationApprovedDomain" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "removedAt" timestamp with time zone, + domain character varying(255) NOT NULL, + "orgId" character varying(100) NOT NULL, + "addedByUserId" character varying(100) NOT NULL, + CONSTRAINT "OrganizationApprovedDomain_domain_check" CHECK ((lower((domain)::text) = (domain)::text)) +); + + +-- +-- TOC entry 251 (class 1259 OID 2494131) +-- Name: OrganizationApprovedDomain_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."OrganizationApprovedDomain" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."OrganizationApprovedDomain_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 279 (class 1259 OID 2494971) +-- Name: OrganizationUser; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."OrganizationUser" ( + id character varying(100) NOT NULL, + "suggestedTier" public."TierEnum", + inactive boolean DEFAULT false NOT NULL, + "joinedAt" timestamp with time zone DEFAULT now() NOT NULL, + "orgId" character varying(100) NOT NULL, + "removedAt" timestamp with time zone, + role public."OrgUserRoleEnum", + "userId" character varying(100) NOT NULL, + tier public."TierEnum" NOT NULL, + "trialStartDate" timestamp with time zone +); + + +-- +-- TOC entry 219 (class 1259 OID 2493642) +-- Name: OrganizationUserAudit; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."OrganizationUserAudit" ( + id integer NOT NULL, + "orgId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "eventDate" timestamp without time zone NOT NULL, + "eventType" public."OrganizationUserAuditEventTypeEnum" NOT NULL +); + + +-- +-- TOC entry 218 (class 1259 OID 2493641) +-- Name: OrganizationUserAudit_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."OrganizationUserAudit" ALTER COLUMN id ADD GENERATED ALWAYS AS IDENTITY ( + SEQUENCE NAME public."OrganizationUserAudit_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 298 (class 1259 OID 2495368) +-- Name: PasswordResetRequest; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."PasswordResetRequest" ( + id integer NOT NULL, + ip cidr NOT NULL, + email public.citext NOT NULL, + "time" timestamp with time zone DEFAULT now() NOT NULL, + token character varying(64) NOT NULL, + "isValid" boolean DEFAULT true NOT NULL +); + + +-- +-- TOC entry 297 (class 1259 OID 2495367) +-- Name: PasswordResetRequest_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."PasswordResetRequest" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."PasswordResetRequest_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 230 (class 1259 OID 2493885) +-- Name: Poll; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Poll" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "deletedAt" timestamp with time zone, + "endedAt" timestamp with time zone, + "createdById" character varying(100) NOT NULL, + "discussionId" character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "threadSortOrder" double precision NOT NULL, + "meetingId" character varying(100), + title character varying(300) +); + + +-- +-- TOC entry 232 (class 1259 OID 2493911) +-- Name: PollOption; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."PollOption" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "pollId" integer NOT NULL, + "voteUserIds" character varying(100)[] DEFAULT ARRAY[]::character varying[] NOT NULL, + title character varying(100) +); + + +-- +-- TOC entry 231 (class 1259 OID 2493910) +-- Name: PollOption_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."PollOption" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."PollOption_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 229 (class 1259 OID 2493884) +-- Name: Poll_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."Poll" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."Poll_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 300 (class 1259 OID 2495381) +-- Name: PushInvitation; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."PushInvitation" ( + id integer NOT NULL, + "userId" character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "denialCount" smallint DEFAULT 0 NOT NULL, + "lastDenialAt" timestamp with time zone +); + + +-- +-- TOC entry 299 (class 1259 OID 2495380) +-- Name: PushInvitation_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."PushInvitation" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."PushInvitation_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 281 (class 1259 OID 2495022) +-- Name: QueryMap; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."QueryMap" ( + id character varying(24) NOT NULL, + query text NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- TOC entry 296 (class 1259 OID 2495339) +-- Name: ReflectPrompt; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."ReflectPrompt" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "removedAt" timestamp with time zone, + description character varying(256) NOT NULL, + "groupColor" character varying(9) NOT NULL, + "sortOrder" character varying(64) NOT NULL COLLATE pg_catalog."C", + question character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "templateId" character varying(100) NOT NULL, + "parentPromptId" character varying(100) +); + + +-- +-- TOC entry 275 (class 1259 OID 2494877) +-- Name: RetroReflection; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."RetroReflection" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + "meetingId" character varying(100) NOT NULL, + "promptId" character varying(111) NOT NULL, + "sortOrder" double precision DEFAULT 0 NOT NULL, + "creatorId" character varying(100), + content character varying(2000) NOT NULL, + "plaintextContent" character varying(2000) NOT NULL, + entities public."GoogleAnalyzedEntity"[] DEFAULT ARRAY[]::public."GoogleAnalyzedEntity"[] NOT NULL, + "sentimentScore" real, + reactjis public."Reactji"[] DEFAULT ARRAY[]::public."Reactji"[] NOT NULL, + "reflectionGroupId" character varying(100) NOT NULL +); + + +-- +-- TOC entry 261 (class 1259 OID 2494277) +-- Name: RetroReflectionGroup; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."RetroReflectionGroup" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + "meetingId" character varying(100) NOT NULL, + "promptId" character varying(111) NOT NULL, + "sortOrder" double precision DEFAULT 0 NOT NULL, + "voterIds" text[] DEFAULT '{}'::character varying[] NOT NULL, + "smartTitle" character varying(255), + title character varying(255), + "discussionPromptQuestion" character varying(2000) +); + + +-- +-- TOC entry 263 (class 1259 OID 2494320) +-- Name: SAML; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."SAML" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "lastUpdatedBy" character varying(100) DEFAULT 'aGhostUser'::character varying NOT NULL, + url character varying(2056), + metadata character varying(65536), + "orgId" character varying(100), + "metadataURL" character varying(2048) +); + + +-- +-- TOC entry 264 (class 1259 OID 2494339) +-- Name: SAMLDomain; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."SAMLDomain" ( + domain character varying(255) NOT NULL, + "samlId" character varying(100), + CONSTRAINT "SAMLDomain_domain_check" CHECK ((lower((domain)::text) = (domain)::text)) +); + + +-- +-- TOC entry 273 (class 1259 OID 2494462) +-- Name: ScheduledJob; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."ScheduledJob" ( + id integer NOT NULL, + "runAt" timestamp with time zone DEFAULT now() NOT NULL, + type public."ScheduledJobTypeEnum" NOT NULL, + "orgId" character varying(100), + "meetingId" character varying(100) +); + + +-- +-- TOC entry 272 (class 1259 OID 2494461) +-- Name: ScheduledJob_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."ScheduledJob_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4528 (class 0 OID 0) +-- Dependencies: 272 +-- Name: ScheduledJob_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."ScheduledJob_id_seq" OWNED BY public."ScheduledJob".id; + + +-- +-- TOC entry 293 (class 1259 OID 2495243) +-- Name: SlackAuth; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."SlackAuth" ( + "isActive" boolean DEFAULT true NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + id character varying(100) NOT NULL, + "botUserId" character varying(100) NOT NULL, + "botAccessToken" character varying(100), + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "defaultTeamChannelId" character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "slackTeamId" character varying(100) NOT NULL, + "slackTeamName" character varying(100) NOT NULL, + "slackUserId" character varying(100) NOT NULL, + "slackUserName" character varying(100) NOT NULL +); + + +-- +-- TOC entry 294 (class 1259 OID 2495281) +-- Name: SlackNotification; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."SlackNotification" ( + id character varying(100) NOT NULL, + event public."SlackNotificationEventEnum" NOT NULL, + "channelId" character varying(100), + "teamId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL +); + + +-- +-- TOC entry 236 (class 1259 OID 2493936) +-- Name: StripeQuantityMismatchLogging; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."StripeQuantityMismatchLogging" ( + id integer NOT NULL, + "userId" character varying(120) DEFAULT NULL::character varying, + "eventTime" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "eventType" character varying(20) NOT NULL, + "stripePreviousQuantity" integer NOT NULL, + "stripeNextQuantity" integer NOT NULL, + "orgUsers" jsonb[] NOT NULL, + "orgId" character varying(100) +); + + +-- +-- TOC entry 235 (class 1259 OID 2493935) +-- Name: StripeQuantityMismatchLogging_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public."StripeQuantityMismatchLogging_id_seq" + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 4529 (class 0 OID 0) +-- Dependencies: 235 +-- Name: StripeQuantityMismatchLogging_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public."StripeQuantityMismatchLogging_id_seq" OWNED BY public."StripeQuantityMismatchLogging".id; + + +-- +-- TOC entry 288 (class 1259 OID 2495123) +-- Name: SuggestedAction; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."SuggestedAction" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + priority smallint DEFAULT 0 NOT NULL, + "removedAt" timestamp with time zone, + type public."SuggestedActionTypeEnum" NOT NULL, + "teamId" character varying(100), + "userId" character varying(100) NOT NULL +); + + +-- +-- TOC entry 309 (class 1259 OID 2495607) +-- Name: Task; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Task" ( + id character varying(100) NOT NULL, + content jsonb NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "createdBy" character varying(100) NOT NULL, + "doneMeetingId" character varying(100), + "dueDate" timestamp with time zone, + integration jsonb, + "integrationHash" character varying(200), + "meetingId" character varying(100), + "plaintextContent" character varying(10000) NOT NULL, + "sortOrder" double precision DEFAULT 0 NOT NULL, + status public."TaskStatusEnum" DEFAULT 'active'::public."TaskStatusEnum" NOT NULL, + tags public."TaskTagEnum"[] DEFAULT ARRAY[]::public."TaskTagEnum"[] NOT NULL, + "teamId" character varying(100) NOT NULL, + "discussionId" character varying(100), + "threadParentId" character varying(100), + "threadSortOrder" integer, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "userId" character varying(100) +); + + +-- +-- TOC entry 228 (class 1259 OID 2493876) +-- Name: TaskEstimate; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TaskEstimate" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "changeSource" public."ChangeSourceEnum" NOT NULL, + name character varying(250) NOT NULL, + label character varying(100) NOT NULL, + "taskId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "meetingId" character varying(100), + "stageId" character varying(100), + "discussionId" character varying(100), + "jiraFieldId" character varying(100), + "githubLabelName" character varying(50), + "azureDevOpsFieldName" character varying(50) +); + + +-- +-- TOC entry 227 (class 1259 OID 2493875) +-- Name: TaskEstimate_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."TaskEstimate" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."TaskEstimate_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 224 (class 1259 OID 2493815) +-- Name: Team; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."Team" ( + id character varying(100) NOT NULL, + name character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "createdBy" character varying(100), + "isArchived" boolean DEFAULT false NOT NULL, + "isPaid" boolean DEFAULT true NOT NULL, + "jiraDimensionFields" jsonb[] DEFAULT '{}'::jsonb[] NOT NULL, + "lastMeetingType" public."MeetingTypeEnum" DEFAULT 'retrospective'::public."MeetingTypeEnum" NOT NULL, + tier public."TierEnum" NOT NULL, + "orgId" character varying(100) NOT NULL, + "isOnboardTeam" boolean DEFAULT false NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "lockMessageHTML" text, + "qualAIMeetingsCount" integer DEFAULT 0 NOT NULL, + "autoJoin" boolean DEFAULT false NOT NULL, + "trialStartDate" timestamp with time zone, + "kudosEmojiUnicode" character varying(100) DEFAULT '❤️'::character varying NOT NULL +); + + +-- +-- TOC entry 308 (class 1259 OID 2495559) +-- Name: TeamInvitation; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TeamInvitation" ( + id character varying(100) NOT NULL, + "acceptedAt" timestamp with time zone, + "acceptedBy" character varying(100), + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "expiresAt" timestamp with time zone NOT NULL, + email public.citext NOT NULL, + "invitedBy" character varying(100) NOT NULL, + "isMassInvite" boolean DEFAULT false NOT NULL, + "meetingId" character varying(100), + "teamId" character varying(100) NOT NULL, + token character varying(200) NOT NULL +); + + +-- +-- TOC entry 262 (class 1259 OID 2494303) +-- Name: TeamMeetingTemplate; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TeamMeetingTemplate" ( + "teamId" character varying(100) NOT NULL, + "templateId" character varying(100) NOT NULL, + "lastUsedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL +); + + +-- +-- TOC entry 280 (class 1259 OID 2494997) +-- Name: TeamMember; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TeamMember" ( + id character varying(100) NOT NULL, + "isNotRemoved" boolean DEFAULT true NOT NULL, + "isLead" boolean DEFAULT false NOT NULL, + "isSpectatingPoker" boolean DEFAULT false NOT NULL, + email public.citext NOT NULL, + "openDrawer" public."TeamDrawerEnum", + picture character varying(2056) NOT NULL, + "preferredName" character varying(100) NOT NULL, + "teamId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- TOC entry 239 (class 1259 OID 2494008) +-- Name: TeamMemberIntegrationAuth; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TeamMemberIntegrationAuth" ( + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "teamId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "providerId" integer NOT NULL, + service public."IntegrationProviderServiceEnum" NOT NULL, + "isActive" boolean DEFAULT true NOT NULL, + "accessToken" character varying(2056), + "refreshToken" character varying(2056), + scopes character varying(255), + "accessTokenSecret" text, + "expiresAt" timestamp with time zone, + channel character varying(255) +); + + +-- +-- TOC entry 242 (class 1259 OID 2494046) +-- Name: TeamPromptResponse; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TeamPromptResponse" ( + id integer NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "updatedAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + "meetingId" character varying(100) NOT NULL, + "userId" character varying(100) NOT NULL, + "sortOrder" integer NOT NULL, + content jsonb NOT NULL, + "plaintextContent" text NOT NULL, + reactjis public."Reactji"[] DEFAULT ARRAY[]::public."Reactji"[] NOT NULL +); + + +-- +-- TOC entry 241 (class 1259 OID 2494045) +-- Name: TeamPromptResponse_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."TeamPromptResponse" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."TeamPromptResponse_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 285 (class 1259 OID 2495066) +-- Name: TemplateDimension; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TemplateDimension" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + name character varying(50) NOT NULL, + description character varying(256) DEFAULT ''::character varying NOT NULL, + "teamId" character varying(100) NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "templateId" character varying(100) NOT NULL, + "scaleId" character varying(100) NOT NULL, + "sortOrder" character varying(64) NOT NULL COLLATE pg_catalog."C", + "removedAt" timestamp with time zone +); + + +-- +-- TOC entry 221 (class 1259 OID 2493656) +-- Name: TemplateRef; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TemplateRef" ( + id character(24) NOT NULL, + template jsonb NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP +); + + +-- +-- TOC entry 282 (class 1259 OID 2495030) +-- Name: TemplateScale; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TemplateScale" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + name character varying(50) NOT NULL, + "teamId" character varying(100) NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + "parentScaleId" character varying(100), + "isStarter" boolean DEFAULT false NOT NULL, + "removedAt" timestamp with time zone +); + + +-- +-- TOC entry 220 (class 1259 OID 2493648) +-- Name: TemplateScaleRef; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TemplateScaleRef" ( + id character(24) NOT NULL, + scale jsonb NOT NULL, + "createdAt" timestamp with time zone DEFAULT CURRENT_TIMESTAMP +); + + +-- +-- TOC entry 284 (class 1259 OID 2495046) +-- Name: TemplateScaleValue; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TemplateScaleValue" ( + id integer NOT NULL, + "templateScaleId" character varying(100) NOT NULL, + "sortOrder" character varying(64) NOT NULL COLLATE pg_catalog."C", + color character varying(9) NOT NULL, + label character varying(18) NOT NULL +); + + +-- +-- TOC entry 283 (class 1259 OID 2495045) +-- Name: TemplateScaleValue_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +ALTER TABLE public."TemplateScaleValue" ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."TemplateScaleValue_id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 276 (class 1259 OID 2494923) +-- Name: TimelineEvent; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."TimelineEvent" ( + id character varying(100) NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "interactionCount" smallint DEFAULT 0 NOT NULL, + "seenCount" smallint DEFAULT 0 NOT NULL, + type public."TimelineEventEnum" NOT NULL, + "userId" character varying(100) NOT NULL, + "teamId" character varying(100), + "orgId" character varying(100), + "meetingId" character varying(100), + "isActive" boolean DEFAULT true NOT NULL +); + + +-- +-- TOC entry 223 (class 1259 OID 2493788) +-- Name: User; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public."User" ( + id character varying(100) NOT NULL, + email public.citext NOT NULL, + "createdAt" timestamp with time zone DEFAULT now() NOT NULL, + "updatedAt" timestamp with time zone DEFAULT now() NOT NULL, + inactive boolean DEFAULT false NOT NULL, + "lastSeenAt" timestamp with time zone DEFAULT now() NOT NULL, + "preferredName" character varying(100) NOT NULL, + tier public."TierEnum" DEFAULT 'starter'::public."TierEnum" NOT NULL, + picture text NOT NULL, + tms character varying(100)[] DEFAULT '{}'::character varying[] NOT NULL, + "featureFlags" character varying(50)[] DEFAULT '{}'::character varying[] NOT NULL, + identities jsonb[] DEFAULT '{}'::jsonb[] NOT NULL, + "lastSeenAtURLs" text[], + "pseudoId" character varying(100), + "newFeatureId" integer, + "overLimitCopy" character varying(500), + "isRemoved" boolean DEFAULT false NOT NULL, + "reasonRemoved" character varying(2000), + rol public."AuthTokenRole", + "payLaterClickCount" smallint DEFAULT 0 NOT NULL, + "isWatched" boolean DEFAULT false NOT NULL, + domain public.citext GENERATED ALWAYS AS (public.split_part(email, '@'::public.citext, 2)) STORED, + "sendSummaryEmail" boolean DEFAULT true NOT NULL, + "isPatient0" boolean DEFAULT false NOT NULL, + "trialStartDate" timestamp with time zone, + "freeCustomRetroTemplatesRemaining" smallint DEFAULT 2 NOT NULL, + "freeCustomPokerTemplatesRemaining" smallint DEFAULT 2 NOT NULL, + "favoriteTemplateIds" text[] DEFAULT ARRAY[]::text[] NOT NULL +); + + +-- +-- TOC entry 3733 (class 2604 OID 2494078) +-- Name: AzureDevOpsDimensionFieldMap id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AzureDevOpsDimensionFieldMap" ALTER COLUMN id SET DEFAULT nextval('public."AzureDevOpsDimensionFieldMap_id_seq"'::regclass); + + +-- +-- TOC entry 3750 (class 2604 OID 2494264) +-- Name: DomainJoinRequest id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."DomainJoinRequest" ALTER COLUMN id SET DEFAULT nextval('public."DomainJoinRequest_id_seq"'::regclass); + + +-- +-- TOC entry 3767 (class 2604 OID 2494430) +-- Name: EmbeddingsJobQueue id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmbeddingsJobQueue" ALTER COLUMN id SET DEFAULT nextval('public."EmbeddingsJobQueue_id_seq"'::regclass); + + +-- +-- TOC entry 3763 (class 2604 OID 2494411) +-- Name: EmbeddingsMetadata id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmbeddingsMetadata" ALTER COLUMN id SET DEFAULT nextval('public."EmbeddingsMetadata_id_seq"'::regclass); + + +-- +-- TOC entry 3718 (class 2604 OID 2493932) +-- Name: GitHubDimensionFieldMap id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitHubDimensionFieldMap" ALTER COLUMN id SET DEFAULT nextval('public."GitHubDimensionFieldMap_id_seq"'::regclass); + + +-- +-- TOC entry 3732 (class 2604 OID 2494067) +-- Name: GitLabDimensionFieldMap id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitLabDimensionFieldMap" ALTER COLUMN id SET DEFAULT nextval('public."GitLabDimensionFieldMap_id_seq"'::regclass); + + +-- +-- TOC entry 3809 (class 2604 OID 2495155) +-- Name: Insight id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Insight" ALTER COLUMN id SET DEFAULT nextval('public."Insight_id_seq"'::regclass); + + +-- +-- TOC entry 3742 (class 2604 OID 2494174) +-- Name: JiraDimensionFieldMap id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraDimensionFieldMap" ALTER COLUMN id SET DEFAULT nextval('public."JiraDimensionFieldMap_id_seq"'::regclass); + + +-- +-- TOC entry 3734 (class 2604 OID 2494091) +-- Name: JiraServerDimensionFieldMap id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraServerDimensionFieldMap" ALTER COLUMN id SET DEFAULT nextval('public."JiraServerDimensionFieldMap_id_seq"'::regclass); + + +-- +-- TOC entry 3774 (class 2604 OID 2494465) +-- Name: ScheduledJob id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ScheduledJob" ALTER COLUMN id SET DEFAULT nextval('public."ScheduledJob_id_seq"'::regclass); + + +-- +-- TOC entry 3719 (class 2604 OID 2493939) +-- Name: StripeQuantityMismatchLogging id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."StripeQuantityMismatchLogging" ALTER COLUMN id SET DEFAULT nextval('public."StripeQuantityMismatchLogging_id_seq"'::regclass); + + +-- +-- TOC entry 4495 (class 0 OID 2495217) +-- Dependencies: 292 +-- Data for Name: AgendaItem; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4432 (class 0 OID 2493855) +-- Dependencies: 226 +-- Data for Name: AtlassianAuth; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4451 (class 0 OID 2494075) +-- Dependencies: 246 +-- Data for Name: AzureDevOpsDimensionFieldMap; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4498 (class 0 OID 2495300) +-- Dependencies: 295 +-- Data for Name: Comment; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4431 (class 0 OID 2493847) +-- Dependencies: 225 +-- Data for Name: Discussion; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4465 (class 0 OID 2494261) +-- Dependencies: 260 +-- Data for Name: DomainJoinRequest; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4490 (class 0 OID 2495102) +-- Dependencies: 287 +-- Data for Name: EmailVerification; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4474 (class 0 OID 2494427) +-- Dependencies: 269 +-- Data for Name: EmbeddingsJobQueue; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4472 (class 0 OID 2494408) +-- Dependencies: 267 +-- Data for Name: EmbeddingsMetadata; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4476 (class 0 OID 2494444) +-- Dependencies: 271 +-- Data for Name: FailedAuthRequest; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4505 (class 0 OID 2495451) +-- Dependencies: 302 +-- Data for Name: FeatureFlag; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."FeatureFlag" VALUES ('f6ad52a2-036a-4673-8df9-aa20f5a06065', 'noAISummary', 'Organization', 'Disables AI summary feature', '2074-10-09 20:55:55.497+00', '2024-10-21 20:55:55.497146+00', '2024-10-21 20:55:55.497146+00'); + + +-- +-- TOC entry 4506 (class 0 OID 2495463) +-- Dependencies: 303 +-- Data for Name: FeatureFlagOwner; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4470 (class 0 OID 2494351) +-- Dependencies: 265 +-- Data for Name: FreemailDomain; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."FreemailDomain" VALUES ('0-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('027168.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('0815.su', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('0sg.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('10mail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('10minutemail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('11mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('123.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('123box.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('123india.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('123mail.cl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('123mail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('123qwe.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('126.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('139.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('150mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('150ml.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('15meg4free.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('163.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('16mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('188.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('189.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1ce.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1chuan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1coolplace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1freeemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1funplace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1internetdrive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1mail.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1mail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1me.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1mum.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1musicrow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1netdrive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1nsyncfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1pad.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1under.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1webave.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1webhighway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('1zhuan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('20email.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('20mail.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('20mail.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('212.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('21cn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('24horas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2911.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2980.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2bmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2d2i.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2die4.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('2trom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3000.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('30minutesmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3126.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('321media.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('33mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('37.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3ammagazine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3dmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3email.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3g.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3mail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('3xl.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('444.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4email.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4email.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4mg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4newyork.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4warding.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4warding.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('4x4man.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('50mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('60minutemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('6ip.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('6mail.cf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('6paq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('74gmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('74.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('7mail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('7mail.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('88.am', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('8848.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('8mail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('8mail.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('97rock.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('99experts.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('a45.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aaamail.zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aamail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aapt.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aaronkwok.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abbeyroadlondon.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abcflash.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abdulnour.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aberystwyth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('about.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abusemail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abv.bg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abwesend.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('abyssmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ac20mail.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('academycougars.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('acceso.or.cr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('access4less.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('accessgcc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('accountant.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('acdcfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ace-of-base.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('acmemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('acninc.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('activist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adam.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('add3000.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('addcom.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('address.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adelphia.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adexec.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adfarrow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adios.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adoption.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ados.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('adrenalinefreak.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('advalvas.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('advantimo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aeiou.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aemail4u.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aeneasmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('afreeinternet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('africamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('africamel.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ag.us.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('agoodmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ahaa.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ahk.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aichi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aircraftmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('airforce.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('airforceemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('airpost.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ajacied.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ajaxapp.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ak47.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aknet.kg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('albawaba.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alex4all.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alexandria.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('algeria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alhilal.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alibaba.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alice.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alive.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aliyun.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('allergist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('allmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alloymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('allracing.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('allsaintsfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alpenjodel.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alphafrau.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alskens.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('altavista.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('altavista.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('altavista.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alternativagratis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alumni.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alumnidirector.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('alvilag.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amazonses.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amele.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('america.hm', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ameritech.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amnetsal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amorki.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amrer.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amuro.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('amuromail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ananzi.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('andylau.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anfmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('angelfire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('angelic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('animail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('animalhouse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('animalwoman.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anjungcafe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('annsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ano-mail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anonmails.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anonymous.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anote.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('another.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anotherdomaincyka.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anotherwin95.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anti-social.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('antisocial.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('antispam24.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('antongijsen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('antwerpen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anymoment.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('anytimenow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aol.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aon.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('apexmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('apmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('apollo.lv', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aport.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aport2000.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('appraiser.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('approvers.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('arabia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('arabtop.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('archaeologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('arcor.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('arcotronics.bg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('arcticmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('argentina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aristotle.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('army.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('armyspy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('arnet.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('art-en-ligne.pro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('artlover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('artlover.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('as-if.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asdasd.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asean-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asheville.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asia-links.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asia-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asiafind.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asianavenue.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asiancityweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asiansonly.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asianwired.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asiapoint.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ass.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('assala.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('assamesemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('astroboymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('astrolover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('astrosfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('astrosfan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('asurfer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atheist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('athenachu.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atina.cl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atl.lv', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atlaswebmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atmc.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atozasia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('atrus.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('att.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('attglobal.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('attymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('au.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('auctioneer.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ausi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('aussiemail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('austin.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('australia.edu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('australiamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('austrosearch.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('autoescuelanerja.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('autograf.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('autorambler.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('avh.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('avia-tonic.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('awsom.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('axoskate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ayna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('azazazatashkent.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('azimiweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('azmeil.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bachelorboy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bachelorgal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('backpackers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('backstreet-boys.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('backstreetboysclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bagherpour.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('baldmama.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('baldpapa.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ballyfinance.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bangkok.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bangkok2000.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bannertown.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('baptistmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('baptized.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('barcelona.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bareed.ws', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bartender.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('baseballmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('basketballmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('batuta.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('baudoinconsulting.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bboy.zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bcvibes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('beddly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('beeebank.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('beenhad.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('beep.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('beer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('beethoven.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('belice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('belizehome.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bell.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bellair.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bellsouth.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('berlin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('berlin.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('berlinexpo.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bestmail.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('betriebsdirektor.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bettergolf.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bharatmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('big1.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigassweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigblue.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigboab.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigfoot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigfoot.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigger.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('biggerbadder.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigmailbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigmir.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigpond.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigpond.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigpond.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigpond.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigpond.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigramp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bigstring.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bikemechanics.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bikeracer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bikeracers.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bikerider.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('billsfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('billsfan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bimla.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bin-wieder-da.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bio-muesli.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('birdlover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('birdowner.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bisons.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bitmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bitpage.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bizhosting.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bk.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blackburnmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blackplanet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blader.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bladesmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blazemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bleib-bei-mir.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blockfilter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blogmyway.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bluebottle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bluehyppo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bluemail.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bluemail.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bluesfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bluewin.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blueyonder.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blushmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('blutig.me', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bmlsports.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boardermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boatracers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bodhi.lawlita.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bol.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bolando.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bollywoodz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boltonfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bombdiggity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bonbon.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bootmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bootybay.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bornnaked.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bostonoffice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boun.cr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bounce.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bounces.amazon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bouncr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('box.az', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('box.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boxbg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boxemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boxformail.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boxfrog.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boximail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('boyzoneclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bradfordfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brasilia.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brazilmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brazilmail.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('breadtimes.press', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('breathe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brennendesreich.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bresnan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brew-master.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brew-meister.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brfree.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('briefemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bright.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('britneyclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brittonsign.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('broadcast.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brokenvalve.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('brusseler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bsdmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('btcmail.pw', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('btconnect.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('btconnect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('btinternet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('btopenworld.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('buerotiger.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('buffymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bullsfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bullsgame.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bumerang.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bumpymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bund.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('burnthespam.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('burstmail.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('buryfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('business-man.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('businessman.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('busta-rhymes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('buyersusa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('bvimailbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('byom.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('c2.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('c2i.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('c3.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('c4.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('c51vsgq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cabacabana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cable.comcast.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cableone.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('caere.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cairomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('calendar-server.bounces.google.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('calidifontain.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('californiamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('callnetuk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('callsign.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('caltanet.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('camidge.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('canada-11.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('canada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('canadianmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('canoemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('canwetalk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('caramail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('care2.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('careerbuildermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('carioca.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cartelera.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cartestraina.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('casablancaresort.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('casema.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cash4u.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cashette.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('casino.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('catcha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('catchamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('catholic.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('catlover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cd2.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('celineclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('celtic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('center-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centermail.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centermail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centermail.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centoper.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centralpets.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centrum.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centrum.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('centurytel.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('certifiedmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cfl.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cgac.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cghost.s-a-d.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chacuo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chaiyomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chammy.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chance2mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chandrasekar.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('charmedmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('charter.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chat.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chattown.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chauhanweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cheatmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chechnya.conf.work', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('check.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('check1check.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cheerful.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chef.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chek.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chello.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chemist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chequemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cheyenneweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chez.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chickmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('china.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('china.net.vg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chinamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chirk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chocaholic.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chong-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('chong-mail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('churchusa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cia-agent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cia.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ciaoweb.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cicciociccio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cincinow.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cinci.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('citiz.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('citlink.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('citromail.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-bath.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-birmingham.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-brighton.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-cambridge.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-coventry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-edinburgh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-lichfield.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-lincoln.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-liverpool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-manchester.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-nottingham.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-oxford.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-swansea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-westminster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-westminster.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('city-of-york.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cityofcardiff.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cityoflondon.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ckaazaza.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('claramail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('classicalfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('classicmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clear.net.nz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clearwire.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clerk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cliffhanger.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clixser.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('close2you.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clrmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('club4x4.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubalfa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubbers.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubducati.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubhonda.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubmember.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubnetnoir.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('clubvdo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cluemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cmpmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cnnsimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cntv.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('codec.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coder.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coid.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coldmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('collectiblesuperstore.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('collector.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('collegeclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('collegemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('colleges.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('columbus.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('columbusrr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('columnist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('comcast.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('comic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('communityconnect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('comporium.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('comprendemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('compuserve.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('computer-freak.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('computer4u.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('computermail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('conexcol.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('conk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('connect4free.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('connectbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('consultant.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('consumerriot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('contractor.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('contrasto.cu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cookiemonster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cool.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coole-files.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolgoose.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolgoose.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolkiwi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coollist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolsend.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coolsite.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cooooool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cooperation.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cooperationtogo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('copacabana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('copper.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cornells.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cornerpub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('corporatedirtbag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('correo.terra.com.gt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cortinet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cotas.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('counsellor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('countrylover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cox.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('coxinet.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cracker.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crapmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crazedanddazed.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crazymailing.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crazysexycool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cristianemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('critterpost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('croeso.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crosshairs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crosswinds.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('crwmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cry4helponline.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('csinibaba.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cuemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('curio-city.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('curryworld.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cute-girl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cuteandcuddly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cutey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cww.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyber-africa.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyber-innovation.club', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyber-matrix.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyber-phone.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyber-wizard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyber4all.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberbabies.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cybercafemaui.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberdude.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberforeplay.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cybergal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cybergrrl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberleports.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cybermail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cybernet.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberservices.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyberspace-asia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cybertrains.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cyclefanz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('cynetcity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dabsol.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dadacasa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('daha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dailypioneer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dallasmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dangerous-minds.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dansegulvet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dasdasdascyka.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('data54.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('davegracey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dawnsonmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dawsonmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dazedandconfused.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dbzmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dcemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deadlymob.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deagot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deal-maker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dearriba.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('death-star.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deliveryman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deneg.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('depechemode.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deseretmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('desertmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('desilota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deskpilot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('destin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('detik.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('deutschland-net.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('devotedcouples.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dezigner.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dfwatson.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('di-ve.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('die-besten-bilder.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('die-genossen.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('die-optimisten.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('die-optimisten.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('diemailbox.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('digibel.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('digital-filestore.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('diplomats.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('directbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dirtracer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('discard.email', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('discard.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('discard.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('disciples.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('discofan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('discoverymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('disign-concept.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('disign-revelation.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('disinfo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dispomail.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('disposable.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dispose.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dm.w3internet.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dmailman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dnainternet.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dnsmadeeasy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('doclist.bounces.google.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('docmail.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('docs.google.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('doctor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dodgit.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dodo.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dodsi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dog.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dogit.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('doglover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dogmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dogsnob.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('doityourself.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb1.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb2.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb3.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb4.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb5.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb6.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb7.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domforfb8.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('domozmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('doneasy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('donjuan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dontgotmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dontmesswithtexas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('doramail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dostmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dotcom.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dotmsg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dott.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('download-privat.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dplanet.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dragoncon.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dropmail.me', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dropzone.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('drotposta.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dubaimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dublin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dublin.ie', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('duck.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dumpmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dumpmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dumpyemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dunlopdriver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dunloprider.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('duno.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('duskmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dutchmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dwp.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dygo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dynamitemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('dyndns.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-apollo.lv', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-mail.com.tr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-mail.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-mail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-mail.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-mailanywhere.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-mails.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('e-tapaal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('earthalliance.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('earthcam.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('earthdome.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('earthling.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('earthlink.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('earthonline.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eastcoast.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eastmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('easy.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('easypost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('easytrashmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ec.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ecardmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ecbsolutions.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('echina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ecolo-online.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ecompare.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('edmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ednatx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('edtnmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('educacao.te.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eelmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ehmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('einrot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('einrot.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eintagsmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eircom.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('elisanet.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('elitemail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('elsitio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('elvis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('elvisfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email-fake.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email-london.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.cbes.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.ee', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.nu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.si', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.su', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email2me.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('email4u.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailacc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailaccount.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailage.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailage.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailasso.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailchoice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailcorner.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailem.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailengine.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailengine.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailer.hubspot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailforyou.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailgo.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailgroups.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailinfive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailit.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailpinoy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailplanet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailplus.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailproxsy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emails.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emails.incisivemedia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emails.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailthe.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailto.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailuser.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailx.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailz.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emailz.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ematic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('embarqmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emeil.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emeil.ir', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('emil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eml.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eml.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('end-war.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('enel.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('engineer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('england.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('england.edu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('englandmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('epage.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('epatra.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ephemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('epix.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('epost.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eposta.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eqqu.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eramail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eresmas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eriga.lv', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('estranet.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ethos.st', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('etoast.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('etrademail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('etranquil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('etranquil.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eudoramail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('europamel.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('europe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('europemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('euroseek.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eurosport.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('every1.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('everyday.com.kh', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('everymail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('everyone.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('everytg.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('examnotes.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('excite.co.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('excite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('excite.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('execs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('exemail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('exg6.exghost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('existiert.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('expressasia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('extenda.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('extended.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eyepaste.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('eyou.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ezcybersearch.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ezmail.egine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ezmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ezrs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('f-m.fm', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('f1fans.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('facebook-email.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('facebook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('facebookmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('facebookmail.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fahr-zur-hoelle.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fake-email.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fake-mail.cf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fake-mail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fake-mail.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fakemailz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('falseaddress.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fansonlymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fansworldwide.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fantasticmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('farang.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('farifluset.mailexpire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('faroweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fast-email.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fast-mail.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fast-mail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastacura.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastchevy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastchrysler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastem.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastemail.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastemailer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastest.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastimap.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastkawasaki.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.fm', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.im', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.mx', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.tw', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmail.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmailbox.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmazda.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmessaging.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastmitsubishi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastnissan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastservice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastsubaru.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastsuzuki.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fasttoyota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fastyamaha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fatcock.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fatflap.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fathersrightsne.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fax.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fbi-agent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fbi.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fdfdsfds.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fea.st', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('federalcontractors.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('feinripptraeger.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('felicitymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('femenino.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fetchmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fettabernett.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('feyenoorder.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ffanet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fiberia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ficken.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fightallspam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('filipinolinks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('financemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('financier.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('findmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('finebody.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fire-brigade.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fireman.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fishburne.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fishfuse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fixmail.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fizmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('flashbox.5july.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('flashmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('flashmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fleckens.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('flipcode.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fmailbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fmgirl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fmguy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fnbmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fnmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('folkfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('foodmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('footard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('footballmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('foothills.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('for-president.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('force9.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('forfree.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('forgetmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fornow.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('forpresident.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fortuncity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fortunecity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('forum.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('foxmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fr33mail.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('francemel.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('free-email.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('free-online.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('free-org.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('free.com.pe', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('free.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeaccess.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeaccount.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeandsingle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freedom.usa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freedomlover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freegates.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeghana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freelance-france.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeler.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.c3.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.com.pk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.et', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.gr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.lt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.ms', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemail.org.mk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemails.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freemeil.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freenet.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freenet.kg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeola.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeola.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeserve.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freestart.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freesurf.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freesurf.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeuk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeuk.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeukisp.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeweb.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freewebemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freeyellow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freezone.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fresnomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freudenkinder.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('freundin.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('friendlymail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('friends-cafe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('friendsfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-africa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-america.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-argentina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-asia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-australia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-belgium.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-brazil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-canada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-china.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-england.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-europe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-france.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-germany.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-holland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-israel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-italy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-japan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-korea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-mexico.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-outerspace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-russia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('from-spain.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromalabama.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromalaska.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromarizona.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromarkansas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromcalifornia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromcolorado.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromconnecticut.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromdelaware.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromflorida.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromgeorgia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromhawaii.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromidaho.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromillinois.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromindiana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromiowa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromjupiter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromkansas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromkentucky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromlouisiana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommaine.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommaryland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommassachusetts.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommiami.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommichigan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromminnesota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommississippi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommissouri.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frommontana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnebraska.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnevada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnewhampshire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnewjersey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnewmexico.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnewyork.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnorthcarolina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromnorthdakota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromohio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromoklahoma.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromoregon.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frompennsylvania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromrhodeisland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromru.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromsouthcarolina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromsouthdakota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromtennessee.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromtexas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromthestates.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromutah.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromvermont.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromvirginia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromwashington.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromwashingtondc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromwestvirginia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromwisconsin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fromwyoming.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('front.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frontier.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frontiernet.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('frostbyte.uk.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fsmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ftc-i.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ftml.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fullmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('funkfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fuorissimo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('furnitureprovider.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fuse.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fut.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fux0ringduh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fwnb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('fxsmails.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('galaxy5.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('galaxyhit.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gamebox.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gamegeek.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gamespotmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gamno.config.work', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('garbage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gardener.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gawab.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gaybrighton.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gaza.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gazeta.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gazibooks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gci.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geecities.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geek.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geek.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geeklife.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gelitik.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gencmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('general-hospital.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gentlemansclub.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geocities.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geography.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('geopia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('germanymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('get.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('get1mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('getairmail.cf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('getairmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('getairmail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('getairmail.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('getonemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ghanamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ghostmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ghosttexter.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('giga4u.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gigileung.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('girl4god.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('givepeaceachance.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('glay.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('glendale.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('globalfree.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('globalpagan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('globalsite.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmail.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmx.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmx.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmx.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmx.li', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gmx.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('go.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('go.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('go.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('go2net.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gocollege.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gocubs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goemailgo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gofree.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gol.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goldenmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goldmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goldtoolbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('golfemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('golfilla.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('golfmail.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gonavy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goodnewsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goodstick.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('googlegroups.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('googlemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('goplay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gorillaswithdirtyarmpits.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gorontalo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gospelfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gothere.uk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gotmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gotmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gotomy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gotti.otherinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gportal.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('graduate.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('graffiti.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gramszu.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('grandmamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('grandmasmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('graphic-designer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('grapplers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gratisweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('greenmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('groupmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('grr.la', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('grungecafe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gtmc.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gua.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('guessmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('guju.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gustr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('guy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('guy2.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('guyanafriends.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gyorsposta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('gyorsposta.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('h-mail.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hab-verschlafen.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('habmalnefrage.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hacccc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hackermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hackermail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hailmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hairdresser.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hamptonroads.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('handbag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('handleit.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hang-ten.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hanmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('happemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('happycounsel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('happypuppy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('harakirimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hardcorefreak.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hartbot.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hawaii.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hawaiiantel.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('heartthrob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('heerschap.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('heesun.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hehe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hello.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hello.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hello.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('helter-skelter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('herediano.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('herono1.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('herp.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('herr-der-mails.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hetnet.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hey.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hhdevel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hidzz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('highmilton.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('highquality.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('highveldmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hilarious.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hiphopfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hispavista.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hitmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hitthe.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hkg.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hkstarphoto.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hockeymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hollywoodkids.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('home-email.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('home.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('home.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('home.no.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('home.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('home.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('homelocator.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('homemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('homestead.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('honduras.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hongkong.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hookup.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hoopsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hopemail.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('horrormail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hot-mail.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hot-shot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hot.ee', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotbot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotbrev.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotfire.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotletter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.co.il', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.co.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.co.nz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.com.tr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.kg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.kz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotmail.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotpop.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotpop3.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hotvoice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('housemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hsuchi.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hu2.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hughes.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('humanoid.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('humn.ws.gy', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hunsa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hurting.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hush.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hushmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('hypernautica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i-connect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i-france.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i-mail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i-p.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i.am', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i12.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('i2pmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iamawoman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iamwaiting.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iamwasted.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iamyours.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('icestorm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ich-bin-verrueckt-nach-dir.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ich-will-net.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('icloud.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('icmsconsultants.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('icq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('icqmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('icrazy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('id-base.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ididitmyway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('idigjesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('idirect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ieatspam.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ieatspam.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ieh-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iespana.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ifoward.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ig.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ignazio.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ignmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ihateclowns.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ihateyoualot.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iheartspam.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iinet.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ijustdontcare.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ikbenspamvrij.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ilkposta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ilovechocolate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ilovejesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ilovetocollect.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ilse.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imaginemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imailbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imap-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imap.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imapmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imel.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imgof.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imgv.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('immo-gerance.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imneverwrong.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imposter.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imstations.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imstressed.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('imtoosexy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('in-box.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('in2jesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iname.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inbax.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inbound.plus', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inbox.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inbox.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inbox.si', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inboxalias.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('incamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('incredimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indeedemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('index.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indexa.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('india.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indiatimes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indo-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indocities.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('indyracers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inerted.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inet.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('info-media.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('info-radio.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('info66.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('infohq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('infomail.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('infomart.or.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('infospacemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('infovia.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inicia.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inmail.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inmail24.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inmano.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inmynetwork.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('innocent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inorbit.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inoutbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('insidebaltimore.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('insight.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('instant-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('instantemailaddress.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('instantmail.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('instruction.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('instructor.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('insurer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('interburp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('interfree.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('interia.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('interlap.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('intermail.co.il', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internet-e-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internet-mail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internet-police.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internetbiz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internetdrive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internetegypt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internetemails.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internetmailing.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('internode.on.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('invalid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('inwind.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iobox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iobox.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iol.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iol.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iowaemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ip3.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ip4.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ip6.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ipoo.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iprimus.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iqemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('irangate.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iraqmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ireland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('irelandmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iremail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('irj.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iroid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('isellcars.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iservejesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('islamonline.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('isleuthmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ismart.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('isonfire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('isp9.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('israelmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ist-allein.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ist-einmalig.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ist-ganz-allein.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ist-willig.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('italymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('itloox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('itmom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ivebeenframed.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ivillage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iwan-fals.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iwmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('iwon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('izadpanah.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jahoopa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jakuza.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('japan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jaydemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jazzandjava.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jazzfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jazzgame.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('je-recycle.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jerusalemmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jet-renovation.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jetable.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jetable.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jetemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jippii.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('job4u.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jobbikszimpatizans.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('joelonsoftware.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('joinme.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jokes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jordanmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('journalist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jourrapide.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jovem.te.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('joymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jpopmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jsrsolutions.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jubiimail.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jump.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('jumpy.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('juniormail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('junk1e.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('junkmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('junkmail.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('juno.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('justemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('justicemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kaazoo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kaffeeschluerfer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kaffeeschluerfer.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kaixo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kalpoint.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kansascity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kapoorweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('karachian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('karachioye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('karbasi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('katamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kayafmmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kbjrmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kcks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('keg-party.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('keinpardon.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('keko.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kellychen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('keromail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('keyemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kgb.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('khosropour.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kickassmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('killermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kimo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kimsdisk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kinglibrary.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kinki-kids.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kissfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kittymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kitznet.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kiwibox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kiwitown.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('klassmaster.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('km.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('knol-power.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kolumbus.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kommespaeter.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('konx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('korea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('koreamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kpnmail.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('krim.ws', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('krongthip.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('krunis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ksanmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ksee24mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kube93mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kukamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kulturbetrieb.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kumarweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('kuwait-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('l33r.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('la.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('labetteraverouge.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ladymail.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lagerlouts.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lags.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lahoreoye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lakmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lamer.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('land.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lankamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('laoeq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('laposte.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lass-es-geschehen.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('last-chance.pro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lastmail.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('latemodels.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('latinmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lavache.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('law.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lawyer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lazyinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('leehom.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('legalactions.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('legalrc.loan', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('legislator.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lenta.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('leonlai.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('letsgomets.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('letterboxes.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('letthemeatspam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('levele.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('levele.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lex.bg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lexis-nexis-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('libero.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('liberomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lick101.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('liebt-dich.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('linkmaster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('linktrader.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('linuxfreemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('linuxmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lionsfan.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('liontrucks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('liquidinformation.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('list.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('listomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('littleapple.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('littleblueroom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.cl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.com.mx', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.com.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.com.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.ie', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.no', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('live.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('liveradio.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('liverpoolfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('llandudno.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('llangollen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lmxmail.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lobbyist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('localbar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('locos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('login-email.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('loh.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lolfreak.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lolito.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('london.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('looksmart.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('looksmart.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('looksmart.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lopezclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('louiskoo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('love.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('loveable.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovecat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovefall.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovefootball.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovelygirl.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lover-boy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovergirl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovesea.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovethebroncos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovethecowboys.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('loveyouforever.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lovingjesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lowandslow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lr7.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lroid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('luso.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('luukku.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('luv2.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lvie.com.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lycos.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lycos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lycos.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lycos.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lycos.ne.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('lycosmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('m-a-i-l.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('m-hmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('m4.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('m4ilweb.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mac.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('macbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('macfreak.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('machinecandy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('macmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('madcreations.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('madonnafan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('madrid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maennerversteherin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maennerversteherin.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maffia.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('magicmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('magspam.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mahmoodweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.bg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-awu.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-box.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-center.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-central.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-easy.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-filter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-me.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-page.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail-tester.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.austria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.az', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.bulgaria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.by', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.com.tr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.ee', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.entrepeneurmag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.freetown.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.gr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.hitthebeach.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.htl22.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.md', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.misterpinball.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.nu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.org.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.pf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.r-o-o-t.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.sisna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.svenz.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.usa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.vasarhely.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail.wtf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail114.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail15.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2007.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aaron.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2abby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2abc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2actor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2admiral.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2adorable.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2adoration.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2adore.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2adventure.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aeolus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aether.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2affection.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2afghanistan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2africa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2agent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ahoy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2air.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2airbag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2airforce.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2airport.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alabama.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alaska.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2albania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alcoholic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alec.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alexa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2algeria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alicia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alien.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2allan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2allen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2allison.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alpha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2alyssa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2amanda.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2amazing.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2amber.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2america.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2american.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2andorra.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2andrea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2andy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2anesthesiologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2angela.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2angola.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ann.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2anna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2anne.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2anthony.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2anything.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aphrodite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2apollo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2april.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aquarius.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2arabia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2arabic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2architect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ares.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2argentina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aries.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2arizona.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2arkansas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2armenia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2army.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2arnold.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2art.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2artemus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2arthur.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2artist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ashley.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ask.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2astronomer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2athena.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2athlete.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2atlas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2atom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2attitude.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2auction.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2aunt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2australia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2austria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2azerbaijan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2baby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bahamas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bahrain.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ballerina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ballplayer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2band.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bangladesh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bank.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2banker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bankrupt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2baptist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2barbados.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2barbara.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2barter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2basketball.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2batter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beach.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beast.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beatles.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beauty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2becky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beijing.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2belgium.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2belize.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ben.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bernard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2betty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beverly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2beyond.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2biker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bill.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2billionaire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2billy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2biologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2black.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2blackbelt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2blake.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2blind.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2blonde.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2blues.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bobby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bolivia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bombay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bonn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bookmark.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2boreas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bosnia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2boston.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2botswana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bradley.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brazil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2breakfast.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bride.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brittany.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2broker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bruce.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brunei.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brunette.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2brussels.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bryan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bug.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2bulgaria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2business.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2buy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ca.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2california.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2calvin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cambodia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cameroon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2canada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cancer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2capeverde.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2capricorn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cardinal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cardiologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2care.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2caroline.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2carolyn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2casey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2caterer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cathy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2catlover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2catwalk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cell.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chad.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2champaign.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2charles.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chef.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chemist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cherry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chicago.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chile.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2china.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chinese.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chocolate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2christian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2christie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2christmas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2christy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2chuck.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cindy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2clark.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2classifieds.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2claude.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cliff.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2clinic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2clint.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2close.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2club.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2coach.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2coastguard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2colin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2college.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2colombia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2color.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2colorado.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2columbia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2comedian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2composer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2computer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2computers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2concert.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2congo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2connect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2connecticut.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2consultant.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2convict.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cory.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2costarica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2country.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2courtney.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cowboy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cowgirl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2craig.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2crave.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2crazy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2create.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2croatia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2crystal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cuba.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2culture.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2curt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2customs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cute.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cutey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cynthia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2cyprus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2czechrepublic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dad.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dale.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dallas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dance.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dancer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2danielle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2danny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2darlene.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2darling.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2darren.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2daughter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dave.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dawn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dealer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2deanna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dearest.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2debbie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2debby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2deer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2delaware.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2delicious.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2demeter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2democrat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2denise.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2denmark.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dennis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dentist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2derek.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2desert.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2devoted.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2devotion.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2diamond.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2diana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2diane.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2diehard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dilemma.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dillon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dinner.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dinosaur.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dionysos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2diplomat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2director.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dirk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2disco.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2diver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2divorced.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2djibouti.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2doctor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2doglover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dominic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dominica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dominicanrepublic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2don.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2donald.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2donna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2doris.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dorothy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2doug.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dough.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2douglas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2downtown.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dream.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dreamer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dude.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dustin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dyke.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2dylan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2earl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2earth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eastend.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2economist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ecuador.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eddie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2edgar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2edwin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2egypt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2electron.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eli.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2elizabeth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ellen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2elliot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2elsalvador.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2elvis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2emergency.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2emily.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2engineer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2english.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2environmentalist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eric.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2erica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2erin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2erinyes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eris.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eritrea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ernie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eros.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2estonia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ethan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ethiopia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eu.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2europe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eurus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2eva.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2evan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2evelyn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2everything.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2exciting.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2expert.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fairy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2faith.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fanatic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fancy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fantasy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2farm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2farmer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fashion.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2feeling.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2female.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fever.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fighter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fiji.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2filmfestival.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2films.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2finance.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2finland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fireman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2firm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fisherman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2flexible.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2florence.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2florida.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2floyd.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fond.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fondness.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2football.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2footballfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2found.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2france.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2frank.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2frankfurt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2franklin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fred.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2freddie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2free.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2freedom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2french.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2freudian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2friendship.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2from.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2fun.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gabon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gabriel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2galaxy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gambia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2games.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gary.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gavin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gemini.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gene.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2genes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2geneva.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2george.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2georgia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gerald.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2german.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2germany.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ghana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gilbert.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2girl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2glen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gloria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2goddess.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gold.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2golfclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2golfer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gordon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2government.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2grab.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2grace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2graham.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2grandma.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2grandpa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2grant.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2greece.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2green.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2greg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2grenada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2gsm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2guard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2guatemala.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2guy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hades.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2haiti.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2handhelds.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hank.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hannah.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2harold.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2harry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hawaii.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2headhunter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2heal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2heather.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2heaven.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hebe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hecate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2heidi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2helen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hell.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2help.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2helpdesk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2henry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hephaestus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hera.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hercules.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2herman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hermes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hespera.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hestia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2highschool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hindu.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hip.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hiphop.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2holland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2holly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hollywood.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2homer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2honduras.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2honey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hongkong.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hope.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2horse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hotel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2houston.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2howard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hugh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2human.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hungary.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hungry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hygeia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hyperspace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2hypnos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ice-cream.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2iceland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2idaho.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2idontknow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2illinois.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2imam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2in.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2india.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2indian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2indiana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2indonesia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2infinity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2intense.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2iowa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2iran.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2iraq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ireland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2irene.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2iris.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2irresistible.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2irving.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2irwin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2isaac.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2israel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2italian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2italy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jackie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jacob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jaime.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jake.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jamaica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2james.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jamie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jane.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2janet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2janice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2japan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2japanese.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jasmine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jason.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2java.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jazz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jed.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jeffrey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jennifer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jenny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jeremy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jerry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jessica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jessie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jew.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jeweler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jimmy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joann.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joanna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jody.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2john.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2join.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jonathan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jones.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jordan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joseph.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2josh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2joy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2juan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2judge.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2judy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2juggler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2julian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2julie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2jumbo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2junk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2justin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2justme.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2k.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kansas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2karate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2karen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2karl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2karma.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kathleen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kathy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2katie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kazakhstan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2keen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2keith.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kelly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kelsey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ken.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kendall.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kennedy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kenneth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kenny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kentucky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kenya.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kerry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kevin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kimberly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2king.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kirk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kiss.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kosher.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kristin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kurt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kuwait.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kyle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2kyrgyzstan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2la.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lacrosse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lance.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lao.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2larry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2latvia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2laugh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2laura.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lauren.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2laurie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lawrence.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lawyer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lebanon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lee.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2leo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2leon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2leonard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2leone.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2leslie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2letter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2liberia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2libertarian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2libra.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2libya.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2liechtenstein.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2life.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2linda.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2linux.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lionel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lipstick.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2liquid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lisa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lithuania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2litigator.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2liz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lloyd.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lois.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lola.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2london.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2looking.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lori.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lou.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2louis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2louisiana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lovable.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2love.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lucky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lucy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lunch.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lust.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2luxembourg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2luxury.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lyle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2lynn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2madagascar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2madison.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2madrid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maggie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mail4.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2malawi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2malaysia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maldives.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mali.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2malta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mambo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2man.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mandy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2manhunter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mankind.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2many.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marcia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2margaret.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2margie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marhaba.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marilyn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marines.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mark.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marriage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2married.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marries.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mars.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marsha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marshallislands.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2martha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2martin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2marvin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mary.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maryland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mason.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2massachusetts.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2matt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2matthew.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maurice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mauritania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mauritius.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2max.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maxwell.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2maybe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mba.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2me4u.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mechanic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2medieval.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2megan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2melanie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2melissa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2melody.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2member.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2memphis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2methodist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mexican.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mexico.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mgz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2miami.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2michael.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2michelle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2michigan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mike.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2milan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2milano.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mildred.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2milkyway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2millennium.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2millionaire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2milton.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mime.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mindreader.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mini.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2minister.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2minneapolis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2minnesota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2miracle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2missionary.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mississippi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2missouri.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mitch.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2model.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2moldova.commail2molly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2monaco.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2money.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mongolia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2monica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2montana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2monty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2moon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2morocco.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2morpheus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mors.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2moscow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2moslem.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mouseketeer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2movies.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mozambique.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mp3.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mrright.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2msright.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2museum.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2music.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2musician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2muslim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2my.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2myboat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mycar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mycell.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mygsm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mylaptop.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mymac.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mypager.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mypalm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2mypc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2myphone.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2myplane.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2namibia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nancy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nasdaq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nathan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nauru.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2navy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2neal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nebraska.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ned.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2neil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nelson.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nemesis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nepal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2netherlands.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2network.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nevada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2newhampshire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2newjersey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2newmexico.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2newyork.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2newzealand.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nicaragua.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nick.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nicole.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2niger.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nigeria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nike.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2no.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2noah.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2noel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2noelle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2normal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2norman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2northamerica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2northcarolina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2northdakota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2northpole.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2norway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2notus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2noway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nowhere.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nuclear.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2nun.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oasis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oceanographer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ohio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ok.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oklahoma.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oliver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2one.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2onfire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2online.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oops.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2open.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ophthalmologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2optometrist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oregon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oscars.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2oslo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2painter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pakistan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2palau.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2panama.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2paraguay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2paralegal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2paris.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2park.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2parker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2party.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2passion.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2patricia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2patrick.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2patty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2paul.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2paula.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2peace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pediatrician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2peggy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pennsylvania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2perry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2persephone.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2persian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2peru.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pete.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2peter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pharmacist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2phil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2philippines.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2phoenix.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2phonecall.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2phyllis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pickup.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pilot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pisces.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2planet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2platinum.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2plato.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pluto.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2podiatrist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2poet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2poland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2policeman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2policewoman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2politician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pop.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2pope.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2popular.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2portugal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2poseidon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2potatohead.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2power.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2presbyterian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2president.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2priest.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2prince.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2princess.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2producer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2professor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2protect.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2psychiatrist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2psycho.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2psychologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2qatar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2queen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rabbi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2race.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2racer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rachel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rainmaker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ralph.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2randy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rap.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rare.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rave.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ray.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2raymond.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2realtor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rebecca.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2recruiter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2recycle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2redhead.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2reed.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2reggie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2register.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2republican.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2resort.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rex.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rhodeisland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rich.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2richard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ricky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ride.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2riley.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rita.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2robert.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2roberta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2robin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rock.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rocker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rod.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rodney.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2romania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rome.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ron.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ronald.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ronnie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rose.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rosie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2roy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rss.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rudy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rugby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2runner.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2russell.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2russia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2russian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rusty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ruth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2rwanda.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ryan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sabrina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2safe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sagittarius.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sailor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2salaam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2samantha.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2samoa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2samurai.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sandra.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sandy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sanfrancisco.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sanmarino.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2santa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sara.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sarah.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2saturn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2saudi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2saudiarabia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2save.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2savings.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2school.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2scientist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2scorpio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2scott.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sean.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2search.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2seattle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2secretagent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2senate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2senegal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sensual.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2seth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sevenseas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sexy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2seychelles.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2shane.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sharon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2shawn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ship.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2shirley.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2shoot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2shuttle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sierraleone.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2simon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2singapore.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2single.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2site.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2skater.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2skier.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sleek.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2slim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2slovakia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2slovenia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2smile.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2smith.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2smooth.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2soccer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2soccerfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2socialist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2soldier.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2somalia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2son.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2song.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sos.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sound.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2southafrica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2southamerica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2southcarolina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2southdakota.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2southkorea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2southpole.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2spain.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2spanish.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2spare.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2spectrum.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2splash.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sponsor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sports.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2srilanka.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stacy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stanley.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2star.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2state.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stephanie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2steve.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2steven.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stewart.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stlouis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stock.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stockholm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stockmarket.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2storage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2store.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2strong.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2student.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2studio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2studio54.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2stuntman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2subscribe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sudan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2superstar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2surfer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2suriname.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2susan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2suzie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2swaziland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sweden.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sweetheart.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2swim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2swimmer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2swiss.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2switzerland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sydney.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2sylvia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2syria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taboo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taiwan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tajikistan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tammy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tango.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tanya.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tanzania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tara.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taurus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taxi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taxidermist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taylor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2taz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2teacher.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2technician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ted.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2telephone.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2teletubbie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tenderness.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tennessee.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tennis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tennisfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2terri.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2terry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2test.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2texas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2thailand.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2therapy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2think.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tickets.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tiffany.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2time.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2timothy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2titanic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2toby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2todd.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2togo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tommy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tonga.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tony.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2touch.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tourist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tracey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tracy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tramp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2travel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2traveler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2travis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2trekkie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2trex.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2triallawyer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2trick.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2trillionaire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2troy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2truck.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2trump.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2try.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tunisia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2turbo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2turkey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2turkmenistan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tv.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tycoon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2tyler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2u4me.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uae.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uganda.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2ukraine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uncle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2unsubscribe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uptown.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uruguay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2usa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2utah.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2uzbekistan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2v.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vacation.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2valentines.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2valerie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2valley.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vamoose.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vanessa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vanuatu.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2venezuela.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2venous.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2venus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vermont.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vickie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2victor.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2victoria.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vienna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vietnam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vince.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2virginia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2virgo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2visionary.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2vodka.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2volleyball.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2waiter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wallstreet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wally.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2walter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2warren.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2washington.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wave.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2way.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2waycool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wayne.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2webmaster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2webtop.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2webtv.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2weird.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wendell.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wendy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2westend.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2westvirginia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2whether.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2whip.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2white.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2whitehouse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2whitney.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2why.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wilbur.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wild.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2willard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2willie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2winner.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wired.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wisconsin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2woman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wonder.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2world.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2worship.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2www.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2wyoming.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2xfiles.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2xox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2yachtclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2yahalla.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2yemen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2yes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2yugoslavia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zack.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zambia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zenith.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zephir.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zeus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zipper.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zoo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zoologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail2zurich.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail3000.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail333.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail4trash.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mail4u.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailandftp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailandnews.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailasia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbolt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbomb.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailboom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbox.as', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbox.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbox.gr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbox.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbox72.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbox80.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailbr.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailc.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailcan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailcat.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailcc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailchoose.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailcity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailclub.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailclub.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maildrop.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maildrop.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maildx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailed.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailexcite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailfa.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailfence.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailforce.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailforspam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailfree.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailfs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailftp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailgenie.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailguard.me', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailhaven.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailhood.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailimate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailinator.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailinator.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailinator.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailinblack.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailingaddress.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailingweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailisent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailismagic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailmate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailme.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailme.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailme24.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailmight.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailmij.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailnator.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailnew.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailops.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailoye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailpanda.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailpick.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailpokemon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailpost.zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailpride.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailproxsy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailpuppy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailquack.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailrock.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailroom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailru.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailsac.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailseal.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailsent.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailservice.ms', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailshuttle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailslapping.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailstart.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailstartplus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailsurf.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailtag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailtemp.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailto.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailtothis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailueberfall.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailup.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailwire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailworks.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailzi.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mailzilla.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maktoob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('malayalamtelevision.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maltesemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mamber.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('manager.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mancity.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mantrafreenet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mantramail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mantraonline.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('manybrain.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('marchmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mariahc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('marijuana.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('marijuana.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('married-not.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('marsattack.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('martindalemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mash4077.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('masrawy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('matmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mauimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mauritius.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maxleft.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('maxmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mbox.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mchsi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('me-mail.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('me.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('medical.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('medscape.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('meetingmall.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('megago.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('megamail.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('megapoint.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mehrani.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mehtaweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('meine-dateien.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('meine-diashow.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('meine-fotos.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('meine-urlaubsfotos.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mekhong.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('melodymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('meloo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('merda.flu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('merda.igg.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('merda.nut.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('merda.usa.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('message.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('message.myspace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('messages.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('metacrawler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('metalfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('metaping.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('metta.lk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mexicomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mezimages.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mfsa.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mierdamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('miesto.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mighty.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('migmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('migmail.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('migumail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('miho-nakayama.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mikrotamanet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('millionaireintraining.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('millionairemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('milmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mindless.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mindspring.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('minister.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('misery.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mittalweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mixmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mjfrogmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ml1.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mlb.bounce.ed10.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mm.st', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mns.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moakt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mobilbatam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mobileninja.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mochamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mohammed.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mohmal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moldova.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moldova.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moldovacc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('momslife.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('monemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('money.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('montevideo.com.uy', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('monumentmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moonman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moose-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mor19.uu.gl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mortaza.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mosaicfx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('moscowmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('most-wanted.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mostlysunny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('motormania.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('movemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('movieluver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mox.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mp4.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mr-potatohead.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mscold.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('msgbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('msn.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('msn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('msn.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mt2015.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mt2016.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mttestdriver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muehlacker.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muell.icu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muellmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muellemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mundomail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('munich.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('music.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('musician.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('musicscene.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muskelshirt.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muslim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('muslimsonline.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mutantweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mvrht.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('my.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('my10minutemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mybox.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mycabin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mycity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mycool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mydomain.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mydotcomaddress.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myfamily.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myfastmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mygo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myiris.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mymacmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mynamedot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mynet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mynetaddress.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mynetstore.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myownemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myownfriends.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mypacks.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mypad.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mypersonalemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myplace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myrambler.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myrealbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myremarq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myself.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myspaceinc.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myspamless.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mystupidjob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mytemp.email', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('mythirdage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('myworldmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('n2.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('n2baseball.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('n2business.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('n2mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('n2soccer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('n2software.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nabc.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nafe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nagpal.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nakedgreens.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('name.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nameplanet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nandomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('naplesnews.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('naseej.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nativestar.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nativeweb.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('naui.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('naver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('navigator.lv', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('navy.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('naz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nc.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nchoicemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('neeva.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nemra1.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nenter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('neo.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nervhq.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.cat', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.lu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-c.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-pager.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net-shopping.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net4b.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('net4you.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netbounce.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netbroadcaster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netby.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netc.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netc.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netc.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netc.lu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netc.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netcenter-vn.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netcmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netcourrier.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netexecutive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netexpressway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netgenie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netizen.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netlane.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netlimit.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netmongol.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netnet.com.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netnoir.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netpiper.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netposta.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netralink.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netscape.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netscapeonline.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netspace.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netspeedway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netsquare.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nettaxi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nettemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netterchef.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netti.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netzero.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netzero.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('netzidiot.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('neue-dateien.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('neuro.md', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('newmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('newmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('newmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('newsboysmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('newyork.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nextmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nexxmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nfmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nicebush.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nicegal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nicholastse.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nicolastse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nightmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nikopage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ninfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nirvanafan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nmail.cf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('noavar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nonpartisan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nonspam.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nonspammer.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('norika-fujiwara.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('norikomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('northgates.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nospammail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nospamthanks.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nowhere.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ntelos.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ntlhelp.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ntlworld.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ntscan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('null.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nullbox.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nur-fuer-spam.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nus.edu.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nwldx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nwytg.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nxt.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nybella.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nyc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nycmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('nzoomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('o-tay.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('o2.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oaklandas-fan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oath.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oceanfree.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('odaymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oddpost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('odmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('office-dateien.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('office-email.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('offroadwarrior.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oicexchange.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oida.icu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oikrach.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('okbank.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('okhuman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('okmad.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('okmagic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('okname.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('okuk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oldies104mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ole.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('olemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('olympist.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('olypmall.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('omaninfo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('omen.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onebox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onenet.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oneoffmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onet.com.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onet.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onet.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oninet.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('online.ie', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('online.ms', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('online.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onlinewiz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onmilwaukee.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('onobox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('op.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('opayq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('openmailbox.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('operafan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('operamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('opoczta.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('optician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('optonline.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('optusnet.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('orange.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('orbitel.bg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('orgmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('orthodontist.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('osite.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('oso.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('otakumail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('our-computer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('our-office.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('our.st', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ourbrisbane.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ourklips.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ournet.md', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outgun.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlawspam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.cl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.co.id', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.co.il', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.co.nz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.co.th', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com.gr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com.pe', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com.tr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.com.vn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.ie', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.kr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.lv', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.my', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.ph', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.sa', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('outlook.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('over-the-rainbow.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ownmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ozbytes.net.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ozemail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pacbell.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pacific-ocean.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pacific-re.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pacificwest.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('packersfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pagina.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pagons.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pakistanmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pakistanoye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('palestinemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pandora.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('papierkorb.me', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('parkjiyoon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('parsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('partlycloudy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('partybombe.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('partyheld.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('partynight.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('parvazi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('passwordmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pathfindermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pconnections.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pcpostal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pcsrock.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pcusers.otherinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pediatrician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('penpen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('peoplepc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('peopleweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pepbot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('perfectmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('perso.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('personal.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('personales.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('petlover.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('petml.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pettypool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pezeshkpour.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pfui.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('phayze.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('phone.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('photo-impact.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('photographer.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('phpbb.uu.gl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('phreaker.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('phus8kajuspa.cu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('physicist.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pianomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pickupman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('picusnet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pigpig.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pinoymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('piracha.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pisem.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pjjkp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planet.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planetaccess.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planetarymotion.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planetearthinter.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planetmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planetmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('planetout.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('plasa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('playersodds.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('playful.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('playstation.sony.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('plus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('plus.google.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('plusmail.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pobox.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pobox.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pochta.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('poczta.fm', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('poczta.onet.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('poetic.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pokemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pokemonpost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pokepost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('polandmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('polbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('policeoffice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('politician.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('polizisten-duzer.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('polyfaust.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pool-sharks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('poond.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('popaccount.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('popmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('popsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('popstar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('portugalmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('portugalmail.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('portugalnet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('positive-thinking.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('post.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('post.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('post.sk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posta.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postaccesslite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postafree.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postaweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.cl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.gl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.no', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('posteo.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postfach.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postino.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postmark.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postmaster.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postmaster.twitter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('postpro.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pousa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('powerfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pp.inet.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('praize.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('premium-mail.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('premiumservice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('presidency.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('press.co.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('priest.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('primposta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('primposta.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('privy-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('privymail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pro.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('probemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('prodigy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('progetplus.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('programist.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('programmer.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('programozo.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('proinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('project2k.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('promessage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('prontomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('protestant.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('protonmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('prydirect.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('psv-supporter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ptd.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('public-files.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('public.usa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('publicist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pulp-fiction.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('punkass.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('purpleturtle.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('put2.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('pwrby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('q.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qatarmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qprfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qrio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quackquack.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quakemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qualityservice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quantentunnel.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qudsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quepasa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quickhosts.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quickmail.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quicknet.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quickwebmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quiklinks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('quikmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qv7.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qwest.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('qwestoffice.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('r-o-o-t.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('raakim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('racedriver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('racefanz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('racingfan.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('racingmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('radicalz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('radiku.ye.vc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('radiologist.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ragingbull.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ralib.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rambler.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ranmamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rastogi.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ratt-n-roll.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rattle-snake.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('raubtierbaendiger.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ravearena.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ravemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('razormail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rccgmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rcn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('realemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reality-concept.club', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reallyfast.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reallyfast.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reallymymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('realradiomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('realtyagent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reborn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reconmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('recycler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('recyclermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rediff.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rediffmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rediffmailpro.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rednecks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('redseven.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('redsfans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('regbypass.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reggaefan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('registerednurses.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('regspaces.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reincarnate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('religious.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('remail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('renren.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('repairman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reply.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('reply.ticketmaster.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('representative.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rescueteam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('resgedvgfed.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('resource.calendar.google.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('resumemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rezai.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rhyta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('richmondhill.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rickymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rin.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('riopreto.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rklips.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ro.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('roadrunner.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('roanokemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rock.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rocketmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rocketship.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rockfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rodrun.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rogers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rome.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('roosh.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rootprompt.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('roughnet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('royal.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rrohio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rsub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rubyridge.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('runbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rushpost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ruttolibero.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('rvshop.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('s-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sabreshockey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sacbeemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('saeuferleber.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('safe-mail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('safrica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sagra.lu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sags-per-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sailormoon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('saintly.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('saintmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sale-sale-sale.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('salehi.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('salesperson.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('samerica.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('samilan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sammimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sandelf.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sanfranmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sanook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sapo.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('saudia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('savelife.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sayhi.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('saynotospams.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sbcglbal.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sbcglobal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sbcglobal.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scandalmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scarlet.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schafmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schizo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schmusemail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schoolemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schoolmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schoolsucks.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schreib-doch-mal-wieder.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('schweiz.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sci.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scientist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scifianime.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scotland.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scotlandmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scottishmail.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scottsboro.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('scubadiving.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('seanet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('search.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('searchwales.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sebil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('seckinmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('secret-police.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('secretary.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('secretservices.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('secure-mail.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('secure-mail.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('seductive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('seekstoyboy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('seguros.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('selfdestructingmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('send.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sendme.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sendspamhere.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sent.as', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sent.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sent.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sentrismail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('serga.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('servemymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('servermaps.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sesmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sexmagnet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('seznam.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shahweb.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shaniastuff.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shared-files.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sharedmailbox.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sharmaweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shaw.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('she.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shieldedmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shinedyoureyes.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.cf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.cu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.gq', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitaway.usa.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shitware.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shockinmytown.cu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shootmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shortmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shotgun.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('showslow.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('shuf.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sialkotcity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sialkotian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sialkotoye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sify.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('silkroad.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sina.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sinamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('singapore.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('singles4jesus.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('singmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('singnet.com.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sinnlos-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('siteposter.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('skafan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('skeefmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('skim.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('skizo.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('skrx.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sky.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('skynet.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slamdunkfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slave-auctions.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slingshot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slippery.email', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slipry.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slo.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('slotter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('smap.4nmv.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('smapxsmap.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('smashmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('smellrear.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('smileyface.comsmithemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('smoothmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sms.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snail-mail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snakebite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snakemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sndt.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sneakemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snet.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sniper.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snkmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snoopymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snowboarding.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('snowdonia.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('socamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('socceramerica.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('soccermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('soccermomz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('social-mailer.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('socialworker.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sociologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sofort-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sofortmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('softhome.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sogou.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sohu.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sol.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('solar-impact.pro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('solcon.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('soldier.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('solution4u.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('solvemail.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('songwriter.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sonnenkinder.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('soodomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('soon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('soulfoodcookbook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sp.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('space-bank.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('space-man.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('space-ship.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('space-travel.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('space.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spacemart.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spacetowns.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spacewar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spainmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spam.2012-2016.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamavert.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spambob.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spambob.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spambog.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spambooger.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spam.care', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamcero.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamdecoy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spameater.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spameater.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamex.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamfree24.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamfree24.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamgoes.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spaminator.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamkill.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spaml.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamoff.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spamstack.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spartapiet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spazmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('speedemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('speedpost.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('speedrules.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('speedrulz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('speedymail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sperke.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spils.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spinfinder.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spl.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spoko.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spoofmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sportemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sportsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sporttruckdriver.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spray.no', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spray.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spybox.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('spymac.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sraka.xyz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('srilankan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ssl-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('st-davids.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stade.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stalag13.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stargateradio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('starmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('starmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('starmedia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('starplace.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('starspath.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('start.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('startkeys.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stinkefinger.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stipte.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stoned.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stones.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stop-my-spam.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stopdropandroll.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('storksite.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('streber24.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('streetwisemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stribmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('strompost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('strongguy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('student.su', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('studentcenter.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('stuffmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('subram.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudanmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudolife.me', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudolife.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudomail.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudomail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudoverse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudoverse.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudoweb.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudoworld.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sudoworld.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('suhabi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('suisse.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sukhumvit.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sunpoint.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sunrise-sunset.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sunsgame.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sunumail.sn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('suomi24.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('superdada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('supereva.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('supermail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('superrito.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('superstachel.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('surat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('surf3.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('surfree.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('surfy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('surgical.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('surimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('survivormail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('susi.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('svk.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swbell.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sweb.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swedenmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sweetville.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sweetxxx.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swift-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swiftdesk.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swingeasyhithard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swingfan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swipermail.zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swirve.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swissinfo.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swissmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('swissmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('switchboardmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('switzerland.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('sx172.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('syom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('syriamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('t-online.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('t.psh.me', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('t2mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tafmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('takuyakimura.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('talk21.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('talkcity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('talkinator.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tamil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tampabay.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tankpolice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tatanova.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tbwt.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tcc.on.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tds.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teachermail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teachers.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teamdiscovery.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teamtulsa.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tech-center.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tech4peace.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('techemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('techie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('technisamail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('technologist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('techscout.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('techspot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teenagedirtbag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tele2.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telebot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telefonica.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teleline.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telenet.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telepac.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telerymd.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('teleworm.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telfort.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telfortglasvezel.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telinco.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telkom.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telpage.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telstra.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('telstra.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('temp-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('temp-mail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('temp.headstrong.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempemail.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempmail.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempmail2.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempmaildemo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempmailer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('temporarioemail.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('temporaryemail.us', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempthe.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tempymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('temtulsa.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tenchiclub.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tenderkiss.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tennismail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('terminverpennt.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('terra.cl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('terra.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('terra.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('terra.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('terra.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('test.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('test.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tfanus.com.er', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tfz.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thai.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thaimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thaimail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thanksnospam.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-african.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-airforce.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-aliens.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-american.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-animal.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-army.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-astronaut.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-beauty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-big-apple.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-biker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-boss.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-brazilian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-canadian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-canuck.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-captain.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-chinese.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-country.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-cowboy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-davis-home.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-dutchman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-eagles.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-englishman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-fastest.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-fool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-frenchman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-galaxy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-genius.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-gentleman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-german.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-gremlin.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-hooligan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-italian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-japanese.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-lair.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-madman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-mailinglist.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-marine.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-master.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-mexican.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-ministry.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-monkey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-newsletter.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-pentagon.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-police.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-prayer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-professional.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-quickest.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-russian.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-snake.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-spaceman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-stock-market.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-student.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-whitehouse.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the-wild-west.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('the18th.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thecoolguy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thecriminals.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thedoghousemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thedorm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theend.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theglobe.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thegolfcourse.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thegooner.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theheadoffice.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theinternetemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thelanddownunder.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('themail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('themillionare.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theoffice.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theplate.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thepokerface.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thepostmaster.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theraces.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theracetrack.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('therapist.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thestreetfighter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('theteebox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thewatercooler.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thewebpros.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thewizzard.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thewizzkid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thezhangs.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thirdage.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thisgirl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thraml.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('throwam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('thundermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tidni.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('timein.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tiscali.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tiscali.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tiscali.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tiscali.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tiscali.lu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tiscali.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tkcity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tmail.ws', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('toast.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('toke.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('toolsource.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('toomail.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('toothfairy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('topchat.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('topgamers.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('topletter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('topmail-files.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('topmail.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('topsurf.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('torchmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('torontomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tortenboxer.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('totalmail.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('totalmusic.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('townisp.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tpg.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trash-amil.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trash-mail.ga', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trash-mail.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trash2010.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trash2011.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trashdevil.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trashymail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('travel.li', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trayna.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trialbytrivia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trickmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trimix.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tritium.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trmailbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tropicalstorm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('truckerz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('truckracer.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('truckracers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('trust-me.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('truthmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tsamail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ttml.co.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tunisiamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('turboprinz.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('turboprinzessin.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('turkey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('turual.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tut.by', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tvstar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('twc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('twcny.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('twinstarsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tx.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('tycoonmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('typemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('u14269.ml', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('u2club.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ua.fm', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uae.ac', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uaemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ubbi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ubbi.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uboot.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uk2.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uk2k.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uk2net.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uk7.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uk8.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ukbuilder.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ukcool.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ukdreamcast.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ukmail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ukmax.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ukr.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uku.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ultra.fyi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ultapulta.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ultrapostman.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ummah.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('umpire.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unbounded.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unforgettable.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uni.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unican.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unihome.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unitybox.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('universal.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uno.ee', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uno.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unofree.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('unterderbruecke.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uol.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uol.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uol.com.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uol.com.mx', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uol.com.ve', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uole.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uole.com.ve', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uolmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('upc.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('upcmail.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('upf.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uplipht.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ureach.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('urgentmail.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('urhen.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uroid.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usa.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usa.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usaaccess.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usanetmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('used-product.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('username.e4ward.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usma.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('usmc.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uswestmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('uyuyuy.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('v-sexi.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vaasfc4.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vahoo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('valemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vampirehunter.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('varbizmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vcmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('velnet.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('velocall.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('verizon.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('verizonmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('verlass-mich-nicht.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('versatel.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('veryfast.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('veryrealemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('veryspeedy.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vfemail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vickaentb.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('videotron.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('viditag.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('viewcastmedia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('viewcastmedia.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vinbazar.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('violinmakers.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.126.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.21cn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.citiz.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.gr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.onet.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.qq.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vip.sina.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vipmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('virgilio.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('virgin.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('virginbroadband.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('virginmedia.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('virtualmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('visitmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('visitweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('visto.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('visualcities.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vivavelocity.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vivianhsu.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vjtimail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vkcode.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vnet.citiz.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vnn.vn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vodafone.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vodafonethuis.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('volcanomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vollbio.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('volloeko.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vomoto.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vorsicht-bissig.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vorsicht-scharf.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vote-democrats.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vote-hillary.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vote-republicans.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vote4gop.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('votenet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vp.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vr9.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('vubby.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('w3.to', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wahoye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('walala.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wales2000.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('walkmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('walkmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wam.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wanadoo.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wanadoo.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('war-im-urlaub.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('warmmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('warpmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('warrior.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('waumail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wazabi.club', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wbdet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wearab.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web-contact.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web-emailbox.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web-ideal.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web-mail.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web-mail.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web-police.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('web.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webave.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webcammail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webcity.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webcontact-france.eu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webdream.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webindia123.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webjump.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webm4il.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webmail.co.yu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webmail.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webmail.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webmails.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webname.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webprogramming.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webstation.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('websurfer.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webtopmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('webuser.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wee.my', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weedmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weekmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weekonline.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wefjo.grn.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weg-werf-email.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wegas.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wegwerf-emails.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wegwerfmail.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wegwerpmailadres.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wehshee.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weibsvolk.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weibsvolk.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('weinenvorglueck.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('welsh-lady.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('westnet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('westnet.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wetrainbayarea.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wfgdfhj.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whale-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whartontx.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whatiaas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whatpaas.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wheelweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whipmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whoever.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whoopymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('whtjddn.33mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wi.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wi.twcbc.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wickmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wideopenwest.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wildmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wilemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('will-hier-weg.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('windowslive.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('windrivers.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('windstream.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wingnutz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('winmail.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('winning.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wir-haben-nachwuchs.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wir-sind-cool.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wirsindcool.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('witty.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wiz.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wkbwmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wmail.cf', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wo.com.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('woh.rr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wolf-web.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wolke7.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wollan.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wombles.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('women-at-work.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wongfaye.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wooow.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('worker.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('workmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('worldemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('worldnet.att.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wormseo.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wosaddict.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wouldilie.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wovz.cu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wowgirl.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wowmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wowway.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wp.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wptamail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wrexham.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('writeme.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('writemeback.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wrongmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wtvhmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wwdg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('www.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('www.e4ward.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('www2000.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wx88.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('wxs.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('x-mail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('x-networks.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('x5g.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xagloo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xaker.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xing886.uu.gl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xmastime.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xms.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xmsg.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xoom.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xoxox.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xpressmail.zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xs4all.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xsecurity.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xsmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xtra.co.nz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xuno.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xww.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xy9ce.tk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xyzfree.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('xzapmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('y7mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ya.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yada-yada.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yaho.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.ae', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.at', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.be', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.ca', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.ch', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.id', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.il', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.kr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.nz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.th', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.co.za', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.ar', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.au', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.cn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.co', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.hk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.is', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.mx', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.my', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.ph', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.sg', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.tr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.tw', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.com.vn', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.cz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.de', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.dk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.es', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.fi', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.gr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.hu', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.ie', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.it', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.jp', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.no', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.pt', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.ro', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoo.se', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yahoofs.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yalla.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yalla.com.lb', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yalook.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yam.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yandex.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yandex.pl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yandex.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yandex.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yapost.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yapped.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yawmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yeah.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yebox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yehey.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yemenmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yepmail.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yert.ye.vc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yesey.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yifan.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ymail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yogotemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yomail.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yopmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yopmail.pp.ua', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yopolis.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yopweb.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('youareadork.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('youmailr.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('your-house.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('your-mail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourinbox.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourlifesucks.cu.cc', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourlover.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourname.freeservers.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yournightmare.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yours.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourssincerely.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yoursubdomain.zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourteacher.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yourwap.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yuuhuu.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('yyhmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('z1p.biz', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('za.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zahadum.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zaktouni.fr', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zeepost.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zetmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zhaowei.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zhouemail.510520.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ziggo.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zionweb.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zip.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zipido.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('ziplip.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zipmail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zipmail.com.br', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zipmax.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zmail.ru', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zoemail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zoemail.org', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zoho.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zohomail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zomg.info', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zonnet.nl', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zoominternet.net', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zubee.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zuvio.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zuzzurello.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zwallet.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zweb.in', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zxcv.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zxcvbnm.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zybermail.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zydecofan.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zzn.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zzom.co.uk', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zzz.com', '2024-10-21 20:55:53.59053+00'); +INSERT INTO public."FreemailDomain" VALUES ('zzz.pl', '2024-10-21 20:55:53.59053+00'); + + +-- +-- TOC entry 4428 (class 0 OID 2493664) +-- Dependencies: 222 +-- Data for Name: GitHubAuth; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4440 (class 0 OID 2493929) +-- Dependencies: 234 +-- Data for Name: GitHubDimensionFieldMap; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4449 (class 0 OID 2494064) +-- Dependencies: 244 +-- Data for Name: GitLabDimensionFieldMap; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4493 (class 0 OID 2495152) +-- Dependencies: 290 +-- Data for Name: Insight; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4444 (class 0 OID 2493988) +-- Dependencies: 238 +-- Data for Name: IntegrationProvider; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4455 (class 0 OID 2494107) +-- Dependencies: 250 +-- Data for Name: IntegrationSearchQuery; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4461 (class 0 OID 2494171) +-- Dependencies: 256 +-- Data for Name: JiraDimensionFieldMap; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4453 (class 0 OID 2494088) +-- Dependencies: 248 +-- Data for Name: JiraServerDimensionFieldMap; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4508 (class 0 OID 2495521) +-- Dependencies: 305 +-- Data for Name: MassInvitation; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4507 (class 0 OID 2495496) +-- Dependencies: 304 +-- Data for Name: MeetingMember; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4459 (class 0 OID 2494149) +-- Dependencies: 254 +-- Data for Name: MeetingSeries; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4494 (class 0 OID 2495197) +-- Dependencies: 291 +-- Data for Name: MeetingSettings; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."MeetingSettings" VALUES ('settings:aGhostTeam:654', '{checkin,SCOPE,ESTIMATE}', 'poker', 'aGhostTeam', 'estimatedEffortTemplate', NULL, NULL, NULL, false, NULL); + + +-- +-- TOC entry 4462 (class 0 OID 2494203) +-- Dependencies: 257 +-- Data for Name: MeetingTemplate; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."MeetingTemplate" VALUES ('teamPrompt', '2024-10-21 20:55:53.427584+00', true, 'Standup', 'aGhostTeam', '2024-10-21 20:55:53.770494+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'teamPrompt', true, true, '/self-hosted/Organization/aGhostOrg/template/teamPrompt.png', NULL, NULL, 'standup'); +INSERT INTO public."MeetingTemplate" VALUES ('action', '2024-10-21 20:55:53.428546+00', true, 'Check-in', 'aGhostTeam', '2024-10-21 20:55:53.770494+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'action', true, true, '/self-hosted/Organization/aGhostOrg/template/action.png', NULL, NULL, 'standup'); +INSERT INTO public."MeetingTemplate" VALUES ('oneOnOneAction', '2024-10-21 20:55:53.494483+00', false, 'One on One', 'aGhostTeam', '2024-10-21 20:55:53.83397+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'action', true, true, '/self-hosted/Organization/aGhostOrg/template/action.png', NULL, NULL, 'standup'); +INSERT INTO public."MeetingTemplate" VALUES ('estimatedEffortTemplate', '2024-10-21 20:53:55.201+00', true, 'Estimated Effort', 'aGhostTeam', '2024-10-21 20:55:54.637204+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'poker', true, true, '/self-hosted/Organization/aGhostOrg/template/estimatedEffortTemplate.png', NULL, NULL, 'estimation'); +INSERT INTO public."MeetingTemplate" VALUES ('moscowPrioritizationTemplate', '2024-10-21 20:55:19.897+00', true, 'MoSCoW Prioritization', 'aGhostTeam', '2024-10-21 20:55:54.637204+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'poker', true, true, '/self-hosted/Organization/aGhostOrg/template/newTemplate.png', NULL, NULL, 'strategy'); +INSERT INTO public."MeetingTemplate" VALUES ('wsjfTemplate', '2024-10-21 20:53:55.201+00', true, 'Weighted Shortest Job First', 'aGhostTeam', '2024-10-21 20:55:54.637204+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'poker', true, true, '/self-hosted/Organization/aGhostOrg/template/wsjfTemplate.png', NULL, NULL, 'estimation'); +INSERT INTO public."MeetingTemplate" VALUES ('ricePrioritizationTemplate', '2024-10-21 20:55:19.897+00', true, 'RICE Prioritization', 'aGhostTeam', '2024-10-21 20:55:54.637204+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'poker', true, true, '/self-hosted/Organization/aGhostOrg/template/newTemplate.png', NULL, NULL, 'strategy'); +INSERT INTO public."MeetingTemplate" VALUES ('360ReviewFeedbackOnDevelopmentTemplate', '2024-10-21 20:55:18.539+00', true, '360 Review: Feedback on Development', 'aGhostTeam', '2024-10-21 20:55:55.247183+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/hopesAndFearsTemplate.png', NULL, NULL, 'feedback'); +INSERT INTO public."MeetingTemplate" VALUES ('agilePostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Agile post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.252978+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('communicationRisksPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Communication risks pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.259091+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('dropAddKeepImproveDAKITemplate', '2024-10-21 20:53:55.206+00', true, 'Drop Add Keep Improve (DAKI)', 'aGhostTeam', '2024-10-21 20:55:55.267235+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/dakiTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('energyLevelsTemplate', '2024-10-21 20:53:55.199+00', true, 'Energy Levels 🔋', 'aGhostTeam', '2024-10-21 20:55:55.269488+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/energyLevelsTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('360ReviewFeedbackOnProgressionTemplate', '2024-10-21 20:55:18.539+00', true, '360 Review: Feedback on Progression', 'aGhostTeam', '2024-10-21 20:55:55.248225+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/mountainClimberTemplate.png', NULL, NULL, 'feedback'); +INSERT INTO public."MeetingTemplate" VALUES ('360ReviewOpenendedFeedbackTemplate', '2024-10-21 20:55:18.539+00', true, '360 Review: Open-ended Feedback', 'aGhostTeam', '2024-10-21 20:55:55.249706+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/heardSeenRespectedHSRTemplate.png', NULL, NULL, 'feedback'); +INSERT INTO public."MeetingTemplate" VALUES ('bestworstCaseScenarioPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Best/worst case scenario pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.255214+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('blindSpotPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Blind spot pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.257388+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('budgetReviewPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Budget review post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.258063+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('successAndFailurePremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Success and failure pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.334456+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('sWOTAnalysisTemplate', '2024-10-21 20:54:28.757+00', true, 'SWOT Analysis 🎯', 'aGhostTeam', '2024-10-21 20:55:55.341145+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/sWOTAnalysisTemplate.png', NULL, NULL, 'strategy'); +INSERT INTO public."MeetingTemplate" VALUES ('teamEfficiencyPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Team efficiency pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.343493+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('threatLevelPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Threat level pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.348757+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('timelinePremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Timeline pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.350962+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('timeManagementPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Time management post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.352133+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('timeTravelPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Time travel post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.353595+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('aChristmasCarolRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Christmas Retrospective 🎅🏼', 'aGhostTeam', '2024-10-21 20:55:55.250881+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/aChristmasCarolRetrospectiveTemplate.png', '2020-01-01 00:00:00+00', '2019-11-15 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('alwaysBeLearningRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Always Be Learning Retrospective 🌱', 'aGhostTeam', '2024-10-21 20:55:55.253674+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/alwaysBeLearningRetrospectiveTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('blamelessPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Blameless post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.256019+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('controlRangePostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Control range post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.260374+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('customerFeedbackAnalysisTemplate', '2024-10-21 20:55:18.197+00', true, 'Customer feedback analysis', 'aGhostTeam', '2024-10-21 20:55:55.261246+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/whatWentWellTemplate.png', NULL, NULL, 'feedback'); +INSERT INTO public."MeetingTemplate" VALUES ('dreamTeamRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Dream Team Retrospective 🦄', 'aGhostTeam', '2024-10-21 20:55:55.26612+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/dreamTeamRetrospectiveTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('engineeringPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Engineering post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.270481+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('highlightsLowlightsTemplate', '2024-10-21 20:54:28.757+00', true, 'Highlights & Lowlights 🎢', 'aGhostTeam', '2024-10-21 20:55:55.283151+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/highlightsLowlightsTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('hopesAndFearsTemplate', '2024-10-21 20:54:28.757+00', true, 'Hopes and Fears 🎭', 'aGhostTeam', '2024-10-21 20:55:55.284908+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/hopesAndFearsTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('iTProjectPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'IT project post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.294002+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('madScientistPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Mad scientist pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.297602+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('midsummerRetrospectiveTemplate', '2024-10-21 20:55:06.962+00', true, 'Midsummer Retrospective', 'aGhostTeam', '2024-10-21 20:55:55.299496+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/midsummerRetrospectiveTemplate.png', '2020-07-01 00:00:00+00', '2020-05-15 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('diwaliRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Diwali Retrospective 🪔', 'aGhostTeam', '2024-10-21 20:55:55.265008+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/diwaliRetrospectiveTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('easterRetrospectiveTemplate', '2024-10-21 20:55:06.962+00', true, 'Easter Retrospective', 'aGhostTeam', '2024-10-21 20:55:55.268613+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/easterRetrospectiveTemplate.png', '2020-04-16 00:00:00+00', '2020-02-28 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('fortuneTellerPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Fortune teller pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.273807+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('gladSadMadTemplate', '2016-06-01 00:00:00+00', true, 'Glad, Sad, Mad', 'aGhostTeam', '2024-10-21 20:55:55.277228+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('herosJourneyTemplate', '2024-10-21 20:54:28.757+00', true, 'Hero’s Journey 👑', 'aGhostTeam', '2024-10-21 20:55:55.282187+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/herosJourneyTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('iguanaCrocodileKomodoDragonPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Iguana, Crocodile, Komodo Dragon pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.287963+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('incidentResponsePostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Incident response post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.292515+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('mountainClimberTemplate', '2024-10-21 20:53:55.199+00', true, 'Mountain Climber ⛰️', 'aGhostTeam', '2024-10-21 20:55:55.300575+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/mountainClimberTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('newYearRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'New Year Retrospective 🗓️', 'aGhostTeam', '2024-10-21 20:55:55.302874+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/newYearRetrospectiveTemplate.png', '2020-01-08 00:00:00+00', '2019-11-22 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('excitedAndWorriedPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Excited and worried pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.271177+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('featureLaunchPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Feature launch post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.272469+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('fourLsTemplate', '2016-06-01 00:00:00+00', true, 'Four L’s', 'aGhostTeam', '2024-10-21 20:55:55.274536+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/fourLsTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('glassHalfemptyPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Glass half-empty pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.277944+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('halloweenRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Halloween Retrospective 🎃', 'aGhostTeam', '2024-10-21 20:55:55.278721+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/halloweenRetrospectiveTemplate.png', '2020-11-07 00:00:00+00', '2020-09-21 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('heardSeenRespectedHSRTemplate', '2024-10-21 20:54:28.766+00', true, 'Heard, Seen, Respected (HSR)', 'aGhostTeam', '2024-10-21 20:55:55.281205+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/heardSeenRespectedHSRTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('hotAirBalloonTemplate', '2024-10-21 20:54:28.757+00', true, 'Hot Air Balloon 🎈', 'aGhostTeam', '2024-10-21 20:55:55.285743+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/hotAirBalloonTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('keepProblemTryTemplate', '2024-10-21 20:54:28.757+00', true, 'Keep, Problem, Try 🤔', 'aGhostTeam', '2024-10-21 20:55:55.295273+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/keepProblemTryTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('marieKondoRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Marie Kondo Retrospective 😌', 'aGhostTeam', '2024-10-21 20:55:55.298696+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/marieKondoRetrospectiveTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('obstacleCoursePremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Obstacle course pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.304208+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('gameShowPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Game show post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.275809+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('handsOnDeckActivityTemplate', '2024-10-21 20:54:28.757+00', true, 'Hands on Deck Activity 🚢', 'aGhostTeam', '2024-10-21 20:55:55.279841+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/handsOnDeckActivityTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('holiRetrospectiveTemplate', '2024-10-21 20:55:06.962+00', true, 'Holi Retrospective', 'aGhostTeam', '2024-10-21 20:55:55.284107+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/holiRetrospectiveTemplate.png', '2020-04-01 00:00:00+00', '2020-02-13 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('howLikelyToFailPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'How likely to fail pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.286653+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('incidentImpactPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Incident impact post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.29147+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('leanCoffeeTemplate', '2024-10-21 20:53:55.206+00', true, 'Lean Coffee ☕', 'aGhostTeam', '2024-10-21 20:55:55.295951+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/leanCoffeeTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('lunarNewYearRetrospectiveTemplate', '2024-10-21 20:55:06.962+00', true, 'Lunar New Year Retrospective', 'aGhostTeam', '2024-10-21 20:55:55.296774+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/lunarNewYearRetrospectiveTemplate.png', '2020-02-25 00:00:00+00', '2019-12-15 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('postincidentReviewTemplate', '2024-10-21 20:55:10.872+00', true, 'Post-incident review', 'aGhostTeam', '2024-10-21 20:55:55.306394+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('postmortemAnalysisTemplate', '2024-10-21 20:55:10.872+00', true, 'Post-mortem analysis', 'aGhostTeam', '2024-10-21 20:55:55.307908+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('questionsCommentsConcernsTemplate', '2024-10-21 20:54:28.757+00', true, 'Questions, Comments, Concerns❓', 'aGhostTeam', '2024-10-21 20:55:55.310427+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/questionsCommentsConcernsTemplate.png', NULL, NULL, 'feedback'); +INSERT INTO public."MeetingTemplate" VALUES ('risksAndPrecautionsPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Risks and precautions pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.317414+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('movieDirectorPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Movie director post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.301848+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('original4Template', '2024-10-21 20:54:28.757+00', true, 'Original 4', 'aGhostTeam', '2024-10-21 20:55:55.305508+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/original4Template.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('remoteWorkPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Remote work post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.311476+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('safariPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Safari pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.319167+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('speedCarTemplate', '2024-10-21 20:54:28.757+00', true, 'Speed Car 🏎️', 'aGhostTeam', '2024-10-21 20:55:55.329435+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/speedCarTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('startStopContinueTemplate', '2016-06-01 00:00:00+00', true, 'Start, Stop, Continue', 'aGhostTeam', '2024-10-21 20:55:55.333559+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/startStopContinueTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('surprisedWorriedInspiredTemplate', '2024-10-21 20:54:28.757+00', true, 'Surprised, Worried, Inspired 😯', 'aGhostTeam', '2024-10-21 20:55:55.340347+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/surprisedWorriedInspiredTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('teamPerformancePostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Team performance post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.345817+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('thanksgivingRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Thanksgiving Retrospective 🥧', 'aGhostTeam', '2024-10-21 20:55:55.347925+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/thanksgivingRetrospectiveTemplate.png', '2020-11-30 00:00:00+00', '2020-10-14 00:00:00+00', 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('whatIfPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'What if... pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.355617+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('whyDidTheProjectFailPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Why did the project fail pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.357785+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('processImprovementPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Process improvement post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.308884+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('resourceAllocationPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Resource allocation pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.312318+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('roseThornBudTemplate', '2024-10-21 20:54:28.757+00', true, 'Rose, Thorn, Bud 🌹', 'aGhostTeam', '2024-10-21 20:55:55.317994+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/roseThornBudTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('saMoLoTemplate', '2024-10-21 20:54:28.757+00', true, 'SaMoLo ⚖️', 'aGhostTeam', '2024-10-21 20:55:55.321127+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/saMoLoTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('scrumSprintPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Scrum sprint pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.323134+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('sixThinkingHatsTemplate', '2024-10-21 20:54:28.757+00', true, 'Six Thinking Hats 🎩', 'aGhostTeam', '2024-10-21 20:55:55.326714+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/sixThinkingHatsTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('stakeholderConcernsPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Stakeholder concerns pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.330067+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('starfishTemplate', '2024-10-21 20:53:55.206+00', true, 'Starfish ⭐', 'aGhostTeam', '2024-10-21 20:55:55.332467+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/starfishTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('riskManagementPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Risk management post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.313892+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('sailboatTemplate', '2016-06-01 00:00:00+00', true, 'Sailboat', 'aGhostTeam', '2024-10-21 20:55:55.320037+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/sailboatTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('scrumRolesPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Scrum roles pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.321799+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('simplePostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Simple post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.325907+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('superheroRetrospectiveTemplate', '2024-10-21 20:54:28.757+00', true, 'Superhero Retrospective 🦸', 'aGhostTeam', '2024-10-21 20:55:55.336585+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/superheroRetrospectiveTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('teamCharterTemplate', '2024-10-21 20:54:28.76+00', true, 'Team Charter', 'aGhostTeam', '2024-10-21 20:55:55.342607+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/teamCharterTemplate.png', NULL, NULL, 'strategy'); +INSERT INTO public."MeetingTemplate" VALUES ('uncertainWatersPremortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Uncertain waters pre-mortem', 'aGhostTeam', '2024-10-21 20:55:55.354756+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'premortem'); +INSERT INTO public."MeetingTemplate" VALUES ('workingStuckTemplate', '2016-06-01 00:00:00+00', true, 'Working & Stuck', 'aGhostTeam', '2024-10-21 20:55:55.361246+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/workingStuckTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('wRAPTemplate', '2024-10-21 20:54:28.757+00', true, 'WRAP 🧞', 'aGhostTeam', '2024-10-21 20:55:55.362229+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/wRAPTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('scrumValuesRetrospectiveTemplate', '2024-10-21 20:54:28.762+00', true, 'Scrum Values Retrospective', 'aGhostTeam', '2024-10-21 20:55:55.324309+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/scrumValuesRetrospectiveTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('softwareProjectPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Software project post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.328214+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('stakeholderSatisfactionPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Stakeholder satisfaction post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.331294+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('superheroPostmortemTemplate', '2024-10-21 20:55:10.872+00', true, 'Superhero post-mortem', 'aGhostTeam', '2024-10-21 20:55:55.335149+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', false, true, '/self-hosted/Organization/aGhostOrg/template/gladSadMadTemplate.png', NULL, NULL, 'postmortem'); +INSERT INTO public."MeetingTemplate" VALUES ('teamRetreatPlanningTemplate', '2024-10-21 20:54:28.757+00', true, 'Team Retreat Planning 🌴', 'aGhostTeam', '2024-10-21 20:55:55.346758+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/teamRetreatPlanningTemplate.png', NULL, NULL, 'strategy'); +INSERT INTO public."MeetingTemplate" VALUES ('threeLittlePigsTemplate', '2024-10-21 20:53:55.199+00', true, 'Three Little Pigs 🐷 🐷 🐷', 'aGhostTeam', '2024-10-21 20:55:55.350236+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/threeLittlePigsTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('whatWentWellTemplate', '2024-10-21 20:53:55.206+00', true, 'What Went Well', 'aGhostTeam', '2024-10-21 20:55:55.357194+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/whatWentWellTemplate.png', NULL, NULL, 'retrospective'); +INSERT INTO public."MeetingTemplate" VALUES ('winningStreakTemplate', '2024-10-21 20:53:55.199+00', true, 'Winning Streak 🏆', 'aGhostTeam', '2024-10-21 20:55:55.358568+00', 'PUBLIC', 'aGhostOrg', NULL, NULL, 'retrospective', true, true, '/self-hosted/Organization/aGhostOrg/template/winningStreakTemplate.png', NULL, NULL, 'retrospective'); + + +-- +-- TOC entry 4463 (class 0 OID 2494242) +-- Dependencies: 258 +-- Data for Name: MeetingTemplateUserFavorite; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4510 (class 0 OID 2495539) +-- Dependencies: 307 +-- Data for Name: NewFeature; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4504 (class 0 OID 2495399) +-- Dependencies: 301 +-- Data for Name: NewMeeting; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4513 (class 0 OID 2495703) +-- Dependencies: 310 +-- Data for Name: Notification; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4481 (class 0 OID 2494949) +-- Dependencies: 278 +-- Data for Name: Organization; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."Organization" VALUES ('aGhostOrg', NULL, false, NULL, '2016-06-01 00:00:00+00', 'Parabol', 0, NULL, NULL, 'https://action-files.parabol.co/production/build/v5.10.1/42342faa774f05b7626fa91ff8374e59.svg', false, NULL, NULL, NULL, 'enterprise', NULL, NULL, NULL, NULL, '2016-06-01 00:00:00+00', '{}'); + + +-- +-- TOC entry 4457 (class 0 OID 2494132) +-- Dependencies: 252 +-- Data for Name: OrganizationApprovedDomain; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4482 (class 0 OID 2494971) +-- Dependencies: 279 +-- Data for Name: OrganizationUser; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."OrganizationUser" VALUES ('aGhostOrganizationUser', NULL, false, '2016-06-01 00:00:00+00', 'aGhostOrg', NULL, 'BILLING_LEADER', 'aGhostUser', 'enterprise', NULL); + + +-- +-- TOC entry 4425 (class 0 OID 2493642) +-- Dependencies: 219 +-- Data for Name: OrganizationUserAudit; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4501 (class 0 OID 2495368) +-- Dependencies: 298 +-- Data for Name: PasswordResetRequest; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4436 (class 0 OID 2493885) +-- Dependencies: 230 +-- Data for Name: Poll; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4438 (class 0 OID 2493911) +-- Dependencies: 232 +-- Data for Name: PollOption; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4503 (class 0 OID 2495381) +-- Dependencies: 300 +-- Data for Name: PushInvitation; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4484 (class 0 OID 2495022) +-- Dependencies: 281 +-- Data for Name: QueryMap; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4499 (class 0 OID 2495339) +-- Dependencies: 296 +-- Data for Name: ReflectPrompt; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."ReflectPrompt" VALUES ('herosJourneyTemplate:cavernPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What challenges lie ahead?', '#DB70DB', '$', 'Cavern', 'aGhostTeam', 'herosJourneyTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('blindSpotPremortemTemplateInvisiblePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What hidden or unknown threats should we pre-empt?', '#8EC7F1', '"', '👻 Invisible', 'aGhostTeam', 'blindSpotPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('original4Template:learningsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What did we learn?', '#FFCC63', '"', 'Learnings 🎓 ', 'aGhostTeam', 'original4Template', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnDevelopmentTemplateOpportunitiesPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What areas would you like to see this colleague develop in? How could they be more helpful to you or the organization?', '#66BC8C', '$', 'Opportunities', 'aGhostTeam', '360ReviewFeedbackOnDevelopmentTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnProgressionTemplateQuestionsPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What questions do you have about this colleague’s roles, work, development, or performance in general?', '#FE975D', '$', 'Questions', 'aGhostTeam', '360ReviewFeedbackOnProgressionTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewOpenendedFeedbackTemplateValuesPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'Share examples of a company value this person has brought to life.', '#FE975D', '$', 'Values', 'aGhostTeam', '360ReviewOpenendedFeedbackTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('customerFeedbackAnalysisTemplateWhereDidOurCustomersGetStuckPrompt', '2024-10-21 20:55:18.197+00', '2024-10-21 20:55:18.197+00', NULL, 'Share verbatim comments and/or observations', '#ED4C86', '"', 'Where did our customers get stuck?', 'aGhostTeam', 'customerFeedbackAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnProgressionTemplateCollaborationPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What should this colleague stop, start, or continue doing when working alongside others?', '#ED4C86', '"', 'Collaboration', 'aGhostTeam', '360ReviewFeedbackOnProgressionTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewOpenendedFeedbackTemplateTrustPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What examples can you give that have helped or hurt you trust this colleague’s ability to assist you with your own work?', '#55C0CF', '!', 'Trust', 'aGhostTeam', '360ReviewOpenendedFeedbackTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewOpenendedFeedbackTemplateInFocusPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What appears to have this colleague’s attention over other efforts? Give some examples.', '#ED4C86', '"', 'In Focus', 'aGhostTeam', '360ReviewOpenendedFeedbackTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('aChristmasCarolRetrospectiveTemplate:christmasFuturePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are your personal or team aspirations for the year ahead?', '#FE975D', '#', 'Christmas Future ⭐ ', 'aGhostTeam', 'aChristmasCarolRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('agilePostmortemTemplateHowEffectiveWereOurCollaborationAndCommunicationPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess your team''s quality of teamwork, information sharing, and cooperation.', '#444258', '"', '🤝 How effective were our collaboration and communication?', 'aGhostTeam', 'agilePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnDevelopmentTemplateRemarkablePrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What does this colleague do that you find remarkable? What do you brag about them to other people?', '#A06BD6', '!', 'Remarkable', 'aGhostTeam', '360ReviewFeedbackOnDevelopmentTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewOpenendedFeedbackTemplateOutOfFocusPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What isn’t getting as much attention as perhaps it should?', '#66BC8C', '#', 'Out of Focus', 'aGhostTeam', '360ReviewOpenendedFeedbackTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('aChristmasCarolRetrospectiveTemplate:allIWantForChristmasIsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s your Christmas wish for the team? What would make your work easier or relieve a burden?', '#DB70DB', '$', 'All I want for Christmas is… 🎁', 'aGhostTeam', 'aChristmasCarolRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('agilePostmortemTemplateHowWellDidWeAdaptAndIterateThroughoutTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Evaluate your team''s ability to respond to changes and implement iterations during the project.', '#DB70DB', '!', '🔄 How well did we adapt and iterate throughout the project?', 'aGhostTeam', 'agilePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('bestworstCaseScenarioPremortemTemplateActionsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What actions can we take to transform the worst-case scenario into the best-case scenario? Develop strategic plans and contingencies to turn challenges into opportunities.', '#66BC8C', '#', '⛳ Actions', 'aGhostTeam', 'bestworstCaseScenarioPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('blamelessPostmortemTemplateWhatCanWeLearnFromTheseSituationsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Reflect on the issues from a blameless perspective, emphasizing the lessons learned rather than assigning fault.', '#DB70DB', '"', '🌱 What can we learn from these situations?', 'aGhostTeam', 'blamelessPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('safariPremortemTemplateGiraffePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What risks can we see from a long way off and pre-empt now?', '#FE975D', '!', '🦒 Giraffe', 'aGhostTeam', 'safariPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnDevelopmentTemplateObstaclesPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What do you see getting in this colleague’s way?', '#55C0CF', '"', 'Obstacles', 'aGhostTeam', '360ReviewFeedbackOnDevelopmentTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnDevelopmentTemplateChallengesPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'Assume you’re working with this colleague for the next 10 years. What behavior isn’t a big deal now, but will get challenging over that time?', '#ED4C86', '#', 'Challenges', 'aGhostTeam', '360ReviewFeedbackOnDevelopmentTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnProgressionTemplateRolesSkillsPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What should this colleague do more of or less of to grow professionally or better the company?', '#55C0CF', '!', 'Roles & Skills', 'aGhostTeam', '360ReviewFeedbackOnProgressionTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewFeedbackOnProgressionTemplatePeopleMattersPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'How has this colleague best helped develop others around them? How can they do better? What should they stop?', '#66BC8C', '#', 'People Matters', 'aGhostTeam', '360ReviewFeedbackOnProgressionTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('360ReviewOpenendedFeedbackTemplateQuestionsPrompt', '2024-10-21 20:55:18.539+00', '2024-10-21 20:55:18.539+00', NULL, 'What questions might you have about the work of the role(s) this colleague performs?', '#A06BD6', '%', 'Questions', 'aGhostTeam', '360ReviewOpenendedFeedbackTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('aChristmasCarolRetrospectiveTemplate:christmasPresentPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are you grateful for? Who has helped you? What processes, skills, or tools make work better? Share some kudos!', '#8EC7F1', '"', 'Christmas Present 🎄', 'aGhostTeam', 'aChristmasCarolRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('communicationRisksPremortemTemplateMisunderstandingsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What potential misunderstandings or misconceptions could cause problems?', '#FFCC63', '$', '🤯 Misunderstandings', 'aGhostTeam', 'communicationRisksPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('aChristmasCarolRetrospectiveTemplate:christmasPastPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s your biggest regret about the year? What do you wish you could have changed?', '#7272E5', '!', 'Christmas Past 👻', 'aGhostTeam', 'aChristmasCarolRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('agilePostmortemTemplateWhatAgilePrinciplesCanWeImproveUponForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Find areas where your team can strengthen their application of Agile methodologies.', '#66BC8C', '#', '🎯 What Agile principles can we improve upon for future projects?', 'aGhostTeam', 'agilePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('alwaysBeLearningRetrospectiveTemplate:thingsILearnedPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What have you learned as an individual or a team in the last period?', '#444258', '!', 'Things I learned 🎓', 'aGhostTeam', 'alwaysBeLearningRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('bestworstCaseScenarioPremortemTemplateBestCaseScenarioPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What does the best case scenario look like? Imagine your project''s ultimate success and the milestones that lead to it.', '#444258', '"', '🙌 Best case scenario', 'aGhostTeam', 'bestworstCaseScenarioPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('blamelessPostmortemTemplateWhatChallengesAroseDuringTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Describe the difficulties encountered, focusing on the situation and the impact, not on individuals or their actions.', '#FE975D', '!', '📉 What challenges arose during the project?', 'aGhostTeam', 'blamelessPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('budgetReviewPostmortemTemplateWhereCanWeMakeAdjustmentsForBetterBudgetAllocationPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Determine opportunities to optimize spending and allocate resources more effectively.', '#7272E5', '#', '💼 Where can we make adjustments for better budget allocation?', 'aGhostTeam', 'budgetReviewPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('communicationRisksPremortemTemplateExternalCommunicationPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What communication issues might arise with stakeholders or clients?', '#66BC8C', '"', '💬 External communication', 'aGhostTeam', 'communicationRisksPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('controlRangePostmortemTemplateWhatWasBeyondOurControlPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Recognize external forces affecting the project but outside your team''s influence.', '#FE975D', '"', '🌪️ What was beyond our control?', 'aGhostTeam', 'controlRangePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('customerFeedbackAnalysisTemplateWhatsMissingForOurCustomersPrompt', '2024-10-21 20:55:18.197+00', '2024-10-21 20:55:18.197+00', NULL, 'Share verbatim comments and/or observations', '#A06BD6', '#', 'What’s missing for our customers?', 'aGhostTeam', 'customerFeedbackAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('diwaliRetrospectiveTemplate:diyasPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we need to guide us forward or help us find our way?', '#66BC8C', '!', 'Diyas', 'aGhostTeam', 'diwaliRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('dreamTeamRetrospectiveTemplate:practicesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What habits, practises, or processes helped the team work well together?', '#FD6157', '!', 'Practices ⚙️', 'aGhostTeam', 'dreamTeamRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('keepPrompt', '2024-10-21 20:54:29.205+00', '2024-10-21 20:54:29.205+00', NULL, 'What should we continue doing?', '#D9D916', '#', 'Keep', 'aGhostTeam', 'dropAddKeepImproveDAKITemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('easterRetrospectiveTemplateSeedsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What new processes would we like to cultivate? Is there something that faded away that we should bring back?', '#FE975D', '"', 'Seeds', 'aGhostTeam', 'easterRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptFullyCharged', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What energized you?', '#52CC52', '!', 'Fully Charged', 'aGhostTeam', 'energyLevelsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('engineeringPostmortemTemplateHowWellDidWeExecuteTheProjectAndOvercomeTechnicalChallengesPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess your team''s ability to manage the project and tackle technical obstacles.', '#8EC7F1', '"', '🔨 How well did we execute the project and overcome technical challenges?', 'aGhostTeam', 'engineeringPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('featureLaunchPostmortemTemplateWhatAspectsDidCustomersAppreciateTheMostPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Highlight the strengths and successful elements of the project from the customers'' perspective.', '#444258', '#', '🏆️ What aspects did customers appreciate the most?', 'aGhostTeam', 'featureLaunchPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('fortuneTellerPremortemTemplateCrystalBallPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What potential issues do we foresee arising during the project?', '#66BC8C', '!', '🔮 Crystal ball', 'aGhostTeam', 'fortuneTellerPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatLearn', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What did you learn?', '#5CA0E5', '"', 'Learned', 'aGhostTeam', 'fourLsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('gameShowPostmortemTemplateWhatWereTheKeyRoundsOfOurProjectGameShowPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Break down the project into distinct stages.', '#66BC8C', '!', '🎮 What were the key "rounds" of our project game show?', 'aGhostTeam', 'gameShowPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatHappy', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What are you happy about?', '#52CC52', '!', 'Glad', 'aGhostTeam', 'gladSadMadTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('glassHalfemptyPremortemTemplateGlassHalfFullPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What do we expect to go well?', '#7272E5', '!', '⏳ Glass half full', 'aGhostTeam', 'glassHalfemptyPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('halloweenRetrospectiveTemplate:ghostsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Boo! What projects or issues caught us by surprise?', '#8EC7F1', '!', 'Ghosts 👻', 'aGhostTeam', 'halloweenRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('handsOnDeckActivityTemplate:navigatorPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are the things you want to avoid, either as a team or in your specific role?', '#7272E5', '#', 'Navigator 🧭', 'aGhostTeam', 'handsOnDeckActivityTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('heardSeenRespectedHSRTemplateHeardPrompt', '2024-10-21 20:54:28.766+00', '2024-10-21 20:54:28.766+00', NULL, 'Think about times or forums in which you felt your voice was not heard. What happened? How did it feel?', '#7340B5', '!', 'Heard', 'aGhostTeam', 'heardSeenRespectedHSRTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('herosJourneyTemplate:heroPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are the attitudes and characteristics that make our team heroic?', '#7272E5', '!', 'Hero', 'aGhostTeam', 'herosJourneyTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('highlightsLowlightsTemplate:highlightsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What was great or exceeded expectations?', '#FE975D', '!', 'Highlights 🙌 ', 'aGhostTeam', 'highlightsLowlightsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('holiRetrospectiveTemplateDancePrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What big wins make us want to dance? What moves or actions should we try next?', '#FFCC63', '#', 'Dance', 'aGhostTeam', 'holiRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('hopesAndFearsTemplate:hopesPrompt-2', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do you hope for in the next period?', '#66BC8C', '!', 'Hopes 🙏', 'aGhostTeam', 'hopesAndFearsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('hotAirBalloonTemplate:sandbagsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking back, what practices or processes are dragging us down, making us slow, or demoralizing us?', '#66BC8C', '"', 'Sandbags', 'aGhostTeam', 'hotAirBalloonTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('howLikelyToFailPremortemTemplateSomewhatLikelyPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What issues are we likely to face?', '#8EC7F1', '"', '🤔 Somewhat likely', 'aGhostTeam', 'howLikelyToFailPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('iguanaCrocodileKomodoDragonPremortemTemplateCrocodilePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What significant and foreseeable threats does this project face?', '#FD6157', '"', '🐊 Crocodile', 'aGhostTeam', 'iguanaCrocodileKomodoDragonPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentImpactPostmortemTemplateWhatWasTheImpactOfTheIncidentPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'List the incidents that took place during the project and discuss their effects.', '#FFCC63', '!', '🔍 What was the impact of the incident?', 'aGhostTeam', 'incidentImpactPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('alwaysBeLearningRetrospectiveTemplate:thingsIWantToLearnPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are the priority things you want to learn as an individual or as a team in the next period?', '#66BC8C', '"', 'Things I want to learn 🧠', 'aGhostTeam', 'alwaysBeLearningRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('bestworstCaseScenarioPremortemTemplateWorstCaseScenarioPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What does the worst case scenario look like? Consider the most significant setbacks and obstacles your project could face.', '#DB70DB', '!', '🤦 Worst case scenario', 'aGhostTeam', 'bestworstCaseScenarioPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('blamelessPostmortemTemplateWhatChangesCanWeMakeToPreventTheseIssuesInTheFuturePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Suggest improvements or preventive measures, keeping in mind the goal is to improve the process, not to blame people.', '#444258', '#', '🔧 What changes can we make to prevent these issues in the future?', 'aGhostTeam', 'blamelessPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('blindSpotPremortemTemplateVisiblePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What obvious threats should we mitigate?', '#7272E5', '!', '👁️ Visible', 'aGhostTeam', 'blindSpotPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('budgetReviewPostmortemTemplateWhatWereTheMajorCostDriversPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify factors that most impacted your project''s financial performance.', '#FFCC63', '"', '📊 What were the major cost drivers?', 'aGhostTeam', 'budgetReviewPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('communicationRisksPremortemTemplateInformationFlowPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What issues might hinder the flow of information between team members or stakeholders?', '#FD6157', '#', '📩 Information flow', 'aGhostTeam', 'communicationRisksPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('controlRangePostmortemTemplateWhatCanWeImproveInOurControlRangePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Determine areas within your control to adjust for future projects.', '#DB70DB', '#', '📈 What can we improve in our control range?', 'aGhostTeam', 'controlRangePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('diwaliRetrospectiveTemplate:rangoliPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What practices or processes are bringing positivity?', '#FD6157', '"', 'Rangoli', 'aGhostTeam', 'diwaliRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('improvePrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What should we improve or revise?', '#7373E5', '$', 'Improve', 'aGhostTeam', 'dropAddKeepImproveDAKITemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('easterRetrospectiveTemplateEasterEggsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What was hidden from sight or caught you by surprise? What did you learn or find out?', '#8EC7F1', '!', 'Easter Eggs', 'aGhostTeam', 'easterRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('featureLaunchPostmortemTemplateWhatChangesCanWeMakeBasedOnCustomerFeedbackPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Think of ways to address customer concerns and enhance your products or services.', '#66BC8C', '$', '🔄 What changes can we make based on customer feedback?', 'aGhostTeam', 'featureLaunchPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('fortuneTellerPremortemTemplateStarsAlignPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'How might these issues impact our project''s success or failure?', '#FD6157', '"', '🌟 Stars align', 'aGhostTeam', 'fortuneTellerPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatMissing', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What was missing?', '#E59545', '#', 'Lacked', 'aGhostTeam', 'fourLsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('gameShowPostmortemTemplateHowDidEachContestantContributeToTheGameShowsFinalePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Discuss each individual''s roles and actions.', '#FFCC63', '#', '🎉 How did each contestant contribute to the game show''s finale?', 'aGhostTeam', 'gameShowPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatImproved', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What could be improved?', '#D9D916', '"', 'Sad', 'aGhostTeam', 'gladSadMadTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('halloweenRetrospectiveTemplate:brainsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What did we learn? What do we need to learn?', '#DB70DB', '#', 'Brains 🧠', 'aGhostTeam', 'halloweenRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('handsOnDeckActivityTemplate:firstMatePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do you want to support closely? What work do you want to have a clear say in?', '#FFCC63', '"', 'First Mate ✋', 'aGhostTeam', 'handsOnDeckActivityTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('heardSeenRespectedHSRTemplateRespectedPrompt', '2024-10-21 20:54:28.766+00', '2024-10-21 20:54:28.766+00', NULL, 'Think about times or forums in which you felt you, your boundaries, or your contributions were not respected. What happened? How did it feel?', '#61B1EB', '#', 'Respected', 'aGhostTeam', 'heardSeenRespectedHSRTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('herosJourneyTemplate:guidePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What guidance or help do you need to be successful?', '#8EC7F1', '"', 'Guide', 'aGhostTeam', 'herosJourneyTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('holiRetrospectiveTemplateSweetsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'Who deserves something sweet, kudos, or a word of thanks?', '#7272E5', '$', 'Sweets', 'aGhostTeam', 'holiRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('hotAirBalloonTemplate:stormCloudsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking ahead, what difficult or tricky things are in store for our team? What things could throw us off course or be dangerous?', '#FD6157', '#', 'Storm Clouds', 'aGhostTeam', 'hotAirBalloonTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('howLikelyToFailPremortemTemplatePossiblePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What issues could we possibly face?', '#FE975D', '#', '🤷 Possible', 'aGhostTeam', 'howLikelyToFailPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('iguanaCrocodileKomodoDragonPremortemTemplateIguanaPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What minor issues can we quickly and easily resolve now?', '#66BC8C', '!', '🦎 Iguana', 'aGhostTeam', 'iguanaCrocodileKomodoDragonPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentImpactPostmortemTemplateWhatLessonsHaveWeLearnedFromThisIncidentPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Determine the key takeaways from each incident.', '#8EC7F1', '#', '💡 What lessons have we learned from this incident?', 'aGhostTeam', 'incidentImpactPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentResponsePostmortemTemplateWhatWasOurIncidentResponseStrategyAndHowWellDidItWorkPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Review your team''s actions and decisions in handling incidents.', '#DB70DB', '!', '⚠️ What was our incident response strategy, and how well did it work?', 'aGhostTeam', 'incidentResponsePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('midsummerRetrospectiveTemplateStrawberryCakePrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'Who deserves some kudos or a word of thanks?', '#7272E5', '$', 'Strawberry Cake', 'aGhostTeam', 'midsummerRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptRopes', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What helped us reach our goal?', '#52CC52', '!', 'Ropes 🧗', 'aGhostTeam', 'mountainClimberTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('movieDirectorPostmortemTemplate2WhatIngredientsDoWeNeedForABlockbusterSequelPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Reflect on elements that could make future projects even more successful.', '#444258', '$', '2️⃣ What ingredients do we need for a blockbuster sequel?', 'aGhostTeam', 'movieDirectorPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('newYearRetrospectiveTemplate:growthWisdomPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking back, how did you grow and what did you learn as an individual or as a team?', '#66BC8C', '!', 'Growth & Wisdom 🌱 ', 'aGhostTeam', 'newYearRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('obstacleCoursePremortemTemplateTwistsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What unexpected changes or surprises might require quick thinking and flexibility?', '#FE975D', '#', '🌪️ Twists', 'aGhostTeam', 'obstacleCoursePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postincidentReviewTemplateWhatCanWeLearnFromTheseIncidentsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Reflect on the lessons these incidents provided.', '#8EC7F1', '#', '🔍 What can we learn from these incidents?', 'aGhostTeam', 'postincidentReviewTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sWOTAnalysisTemplate:opportunitiesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Where can we improve or what can we take advantage of?', '#444258', '#', 'Opportunities', 'aGhostTeam', 'sWOTAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('budgetReviewPostmortemTemplateHowDidOurActualSpendingCompareToTheInitialBudgetPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Compare your project''s financial performance against the planned budget.', '#FD6157', '!', '💰 How did our actual spending compare to the initial budget?', 'aGhostTeam', 'budgetReviewPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('communicationRisksPremortemTemplateInternalCommunicationPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What communication issues might arise within the team?', '#444258', '!', '📣 Internal communication', 'aGhostTeam', 'communicationRisksPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('diwaliRetrospectiveTemplate:ravanaPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What demons, projects, or problems are cursing us?', '#7272E5', '$', 'Ravana', 'aGhostTeam', 'diwaliRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('dreamTeamRetrospectiveTemplate:valuesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What values and teamwork principles make us successful', '#FFCC63', '"', 'Values 💜', 'aGhostTeam', 'dreamTeamRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('addPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What should we try or adopt?', '#E55C5C', '"', 'Add', 'aGhostTeam', 'dropAddKeepImproveDAKITemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('easterRetrospectiveTemplateChocolatePrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'Who deserves some kudos or a word of thanks?', '#444258', '$', 'Chocolate', 'aGhostTeam', 'easterRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptLowBattery', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What depleted you?', '#E55C5C', '"', 'Low Battery', 'aGhostTeam', 'energyLevelsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('engineeringPostmortemTemplateWhatNuggetsOfWisdomCanWeMineForFutureEngineeringProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify best practices, areas for improvement, and other insights to optimize future engineering projects.', '#FE975D', '#', '🤓 What nuggets of wisdom can we mine for future engineering projects?', 'aGhostTeam', 'engineeringPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('excitedAndWorriedPremortemTemplateWhatAreYouExcitedAboutPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, '', '#DB70DB', '!', '🤩 What are you excited about?', 'aGhostTeam', 'excitedAndWorriedPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('featureLaunchPostmortemTemplateWhatFeedbackDidWeReceiveFromCustomersPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Collect and categorize customer feedback from various channels.', '#FE975D', '!', '📣 What feedback did we receive from customers?', 'aGhostTeam', 'featureLaunchPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatHappen', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What did you want to happen?', '#AC73E5', '$', 'Longed for', 'aGhostTeam', 'fourLsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('gameShowPostmortemTemplateWhatWereTheWinsAndLossesDuringEachRoundPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify successes and challenges at each stage.', '#FD6157', '"', '🏆 What were the wins and losses during each round?', 'aGhostTeam', 'gameShowPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('halloweenRetrospectiveTemplate:candyPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Who deserves candy? What went well? Who do you want to give kudos to?', '#444258', '$', 'Candy 🍬', 'aGhostTeam', 'halloweenRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('handsOnDeckActivityTemplate:captainPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What things do you see yourself leading on? What things do you want to lead the team on? What do you want to take responsibility for?', '#FD6157', '!', 'Captain 🧑‍✈️', 'aGhostTeam', 'handsOnDeckActivityTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('highlightsLowlightsTemplate:kudosPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Who helped you or deserves some appreciation?', '#444258', '#', 'Kudos ❤️', 'aGhostTeam', 'highlightsLowlightsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('holiRetrospectiveTemplateColorsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What color represents our recent work? Why?', '#66BC8C', '!', 'Colors', 'aGhostTeam', 'holiRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('hotAirBalloonTemplate:clearSkiesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking ahead, how could we avoid or manage threats and challenges? How could we push through them to reach clearer skies?', '#FFCC63', '$', 'Clear Skies', 'aGhostTeam', 'hotAirBalloonTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('howLikelyToFailPremortemTemplateHighlyLikelyPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What issues are we highly likely to face?', '#7272E5', '!', '💯 Highly likely', 'aGhostTeam', 'howLikelyToFailPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('iguanaCrocodileKomodoDragonPremortemTemplateKomodoDragonPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What big, scary, and unpredictable challenges might we encounter?', '#FFCC63', '#', '🐉 Komodo Dragon', 'aGhostTeam', 'iguanaCrocodileKomodoDragonPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentImpactPostmortemTemplateWhatWasTheRootCausePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify the underlying causes of each incident.', '#7272E5', '"', '🌳 What was the root cause?', 'aGhostTeam', 'incidentImpactPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentResponsePostmortemTemplateWhatImprovementsCanWeMakeToOurIncidentResponseForFutureProjectsPro', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Develop strategies to improve your team''s incident readiness.', '#FD6157', '$', '📈 What improvements can we make to our incident response for future projects?', 'aGhostTeam', 'incidentResponsePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('iTProjectPostmortemTemplateWhatGapsOrChallengesDidWeFaceInOurITInfrastructurePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Recognize any technology-related issues or shortcomings.', '#DB70DB', '"', '🔧 What gaps or challenges did we face in our IT infrastructure?', 'aGhostTeam', 'iTProjectPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('keepProblemTryTemplate:problemPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s not going well?', '#66BC8C', '"', 'Problem', 'aGhostTeam', 'keepProblemTryTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('toDiscussPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What should we talk about? We''ll group related items into topics and vote on them to decide what to chat about', '#45E5E5', '!', 'To Discuss', 'aGhostTeam', 'leanCoffeeTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('lunarNewYearRetrospectiveTemplateHongbaoPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'Who deserves a red envelope with kudos and some words of appreciation?', '#8EC7F1', '!', 'Hongbao 🧧', 'aGhostTeam', 'lunarNewYearRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('madScientistPremortemTemplateInnovativeSolutionsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'How can we invent creative strategies to counter these threats?', '#7272E5', '#', '💡 Innovative solutions', 'aGhostTeam', 'madScientistPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('marieKondoRetrospectiveTemplate:whatSparksJoyPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What processes, tools, and skills are serving you well?', '#DB70DB', '!', 'What Sparks Joy?', 'aGhostTeam', 'marieKondoRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('midsummerRetrospectiveTemplateSchnappsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What’s been hard to swallow, admit, or realize about our work?', '#FD6157', '"', 'Schnapps', 'aGhostTeam', 'midsummerRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWeather', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'How did we feel about our work?', '#5CA0E5', '#', 'Weather 🌡️', 'aGhostTeam', 'mountainClimberTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('movieDirectorPostmortemTemplateHowDidEachCastMemberContributeToThePlotPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Discuss each team member''s roles and actions.', '#FE975D', '"', '🎥 How did each cast member contribute to the plot?', 'aGhostTeam', 'movieDirectorPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('newYearRetrospectiveTemplate:greatestHitsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking back, what were your or the team’s greatest accomplishments', '#FD6157', '"', 'Greatest Hits 🏆', 'aGhostTeam', 'newYearRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('obstacleCoursePremortemTemplatePitfallsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What hidden traps or pitfalls could cause setbacks, delays, or negative impacts on the project?', '#8EC7F1', '"', '🕳️ Pitfalls', 'aGhostTeam', 'obstacleCoursePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('original4Template:improvementsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What should we do differently next time?', '#7272E5', '#', 'Improvements ♻️ ', 'aGhostTeam', 'original4Template', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('controlRangePostmortemTemplateWhatWasWithinOurControlPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify factors your team could influence or manage.', '#8EC7F1', '!', '🎛️ What was within our control?', 'aGhostTeam', 'controlRangePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('customerFeedbackAnalysisTemplateWhatsWorkingForOurCustomersPrompt', '2024-10-21 20:55:18.197+00', '2024-10-21 20:55:18.197+00', NULL, 'Share verbatim comments and/or observations', '#55C0CF', '!', 'What’s working for our customers?', 'aGhostTeam', 'customerFeedbackAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('diwaliRetrospectiveTemplate:lakshmiPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we need to tidy or clean up? What processes or backlog items need purifying?', '#FFCC63', '#', 'Lakshmi', 'aGhostTeam', 'diwaliRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('dreamTeamRetrospectiveTemplate:absencePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What practices, processes or skills weren’t present in the team?', '#7272E5', '#', 'Absence 🤔', 'aGhostTeam', 'dreamTeamRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('dropPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What should we stop?', '#52CC52', '!', 'Drop', 'aGhostTeam', 'dropAddKeepImproveDAKITemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('easterRetrospectiveTemplateHopePrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What did you hope for? What are you hoping for next?', '#DB70DB', '#', 'Hope', 'aGhostTeam', 'easterRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptSprintEnergy', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What''s your energy level going into the next Sprint?', '#7373E5', '#', 'Sprint Energy', 'aGhostTeam', 'energyLevelsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('engineeringPostmortemTemplateDidOurProjectDesignAndPlanningMeetExpectationsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess how your project''s design and planning helped meet your engineering goals.', '#7272E5', '!', '📐 Did our project design and planning meet expectations?', 'aGhostTeam', 'engineeringPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('excitedAndWorriedPremortemTemplateWhatAreYouWorriedAboutPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, '', '#444258', '"', '😨 What are you worried about?', 'aGhostTeam', 'excitedAndWorriedPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('featureLaunchPostmortemTemplateWhatWereTheMostCommonCustomerPainPointsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify recurring issues and areas of dissatisfaction.', '#DB70DB', '"', '🎯 What were the most common customer pain points?', 'aGhostTeam', 'featureLaunchPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('fortuneTellerPremortemTemplateChangingFatePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What actions can we take now to alter the course of our project for the better?', '#FFCC63', '#', '✨ Changing fate', 'aGhostTeam', 'fortuneTellerPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatWell', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What went well?', '#52CC52', '!', 'Liked', 'aGhostTeam', 'fourLsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('gameShowPostmortemTemplateWhatGameRulesShouldWeModifyForTheNextSeasonPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Consider changes that could improve the process for future projects.', '#7272E5', '$', '🕹️ What game rules should we modify for the next season?', 'aGhostTeam', 'gameShowPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatAngry', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What are you angry or disappointed about?', '#E55C5C', '#', 'Mad', 'aGhostTeam', 'gladSadMadTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('glassHalfemptyPremortemTemplateGlassHalfEmptyPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What do we worry will go wrong?', '#8EC7F1', '"', '⌛ Glass half empty', 'aGhostTeam', 'glassHalfemptyPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('halloweenRetrospectiveTemplate:zombiesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What feels slow? What are we dragging our feet on?', '#FE975D', '"', 'Zombies 🧟', 'aGhostTeam', 'halloweenRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('handsOnDeckActivityTemplate:deckScrubberPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are you happy to help out with, but would rather take a back seat on?', '#8EC7F1', '$', 'Deck Scrubber 🧼', 'aGhostTeam', 'handsOnDeckActivityTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('heardSeenRespectedHSRTemplateSeenPrompt', '2024-10-21 20:54:28.766+00', '2024-10-21 20:54:28.766+00', NULL, 'Think about times or forums in which you felt you were not seen or your efforts were not recognized. What happened? How did it feel?', '#F23B31', '"', 'Seen', 'aGhostTeam', 'heardSeenRespectedHSRTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('herosJourneyTemplate:treasurePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s your team’s end goal? What does success look like?', '#FE975D', '#', 'Treasure', 'aGhostTeam', 'herosJourneyTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('highlightsLowlightsTemplate:lowlightsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What didn’t go well or made us feel down?', '#DB70DB', '"', 'Lowlights 😫 ', 'aGhostTeam', 'highlightsLowlightsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('holiRetrospectiveTemplateMusicPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'Are we all dancing to the same rhythm? Where were we in sync? When did we fall out of sync?', '#FD6157', '"', 'Music', 'aGhostTeam', 'holiRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('hopesAndFearsTemplate:fearsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are you worried about for the next period?', '#FD6157', '"', 'Fears 🧟 ', 'aGhostTeam', 'hopesAndFearsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('hotAirBalloonTemplate:hotAirPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking back, what practices or processes elevate our team and help us reach great new heights?', '#444258', '!', 'Hot Air', 'aGhostTeam', 'hotAirBalloonTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentImpactPostmortemTemplateWhatChangesCanWeMakeToPreventSimilarIncidentsInTheFuturePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Create plans to minimize the chances of recurrence.', '#FE975D', '$', '🔧 What changes can we make to prevent similar incidents in the future?', 'aGhostTeam', 'incidentImpactPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentResponsePostmortemTemplateWereOurIncidentResponsePlansAndProceduresEffectivePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Evaluate the usefulness of existing approaches and protocols.', '#66BC8C', '#', '🚨 Were our incident response plans and procedures effective?', 'aGhostTeam', 'incidentResponsePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('iTProjectPostmortemTemplateHowCanWeEnhanceOurTechnologyStackForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Formulate strategies to upgrade your IT infrastructure and tools, considering the insights from this post-mortem.', '#444258', '#', '📈 How can we enhance our technology stack for future projects?', 'aGhostTeam', 'iTProjectPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('keepProblemTryTemplate:keepPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What should we continue doing?', '#444258', '!', 'Keep', 'aGhostTeam', 'keepProblemTryTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('lunarNewYearRetrospectiveTemplateFirecrackerPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What caught us by surprise or gave us a fright?', '#DB70DB', '#', 'Firecracker 🧨', 'aGhostTeam', 'lunarNewYearRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('madScientistPremortemTemplateFreakAccidentsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What surprising challenges could throw our project off course?', '#FFCC63', '"', '🧪 Freak accidents', 'aGhostTeam', 'madScientistPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('marieKondoRetrospectiveTemplate:thankYouAndGoodbyePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do you want to stop doing, having, or using, or just stop from happening?', '#444258', '"', 'Thank you and Goodbye', 'aGhostTeam', 'marieKondoRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('midsummerRetrospectiveTemplateLongestDayPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What feels like it took too long or was never-ending?', '#FFCC63', '#', 'Longest Day', 'aGhostTeam', 'midsummerRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptBoulders', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What stood in our way?', '#AC73E5', '"', 'Boulders ⛰️', 'aGhostTeam', 'mountainClimberTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('movieDirectorPostmortemTemplateWhatWasThePlotOfOurProjectMoviePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Narrate the project''s journey, including pivotal events and plot twists.', '#8EC7F1', '!', '🎬 What was the plot of our project movie?', 'aGhostTeam', 'movieDirectorPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamCharterTemplateValuesPrompt', '2024-10-21 20:54:28.76+00', '2024-10-21 20:54:28.76+00', NULL, 'What values guide our work together and with others?', '#FD6157', '"', 'Values', 'aGhostTeam', 'teamCharterTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('incidentResponsePostmortemTemplateWhichAspectsOfOurResponseWereMostEffectiveAndWhichWereLessSuccessf', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify areas where your team excelled and those needing improvement.', '#444258', '"', '⛑️ Which aspects of our response were most effective, and which were less successful?', 'aGhostTeam', 'incidentResponsePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('iTProjectPostmortemTemplateWhichTechnologyToolsAndPlatformsWereMostBeneficialDuringTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify the most valuable and effective components of your technology stack.', '#FE975D', '!', '💻 Which technology tools and platforms were most beneficial during the project?', 'aGhostTeam', 'iTProjectPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('keepProblemTryTemplate:tryPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s the smallest next step we could take to resolve our problems?', '#FD6157', '#', 'Try', 'aGhostTeam', 'keepProblemTryTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('lunarNewYearRetrospectiveTemplateCoupletsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What important messages should we remember for guidance?', '#FE975D', '"', 'Couplets 🎊 ', 'aGhostTeam', 'lunarNewYearRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('madScientistPremortemTemplateCrazyExperimentsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What wild and unexpected risks might we face?', '#FD6157', '!', '⚗️ Crazy experiments', 'aGhostTeam', 'madScientistPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('marieKondoRetrospectiveTemplate:thingsToUpcyclePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What could serve you well if it was changed or improved?', '#66BC8C', '#', 'Things to Upcycle', 'aGhostTeam', 'marieKondoRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('midsummerRetrospectiveTemplateWreathsPrompt', '2024-10-21 20:55:06.962+00', '2024-10-21 20:55:06.962+00', NULL, 'What processes and practices are binding us together and making us stronger?', '#66BC8C', '!', 'Wreaths', 'aGhostTeam', 'midsummerRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptFirstAid', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What more do we need to reach our goals?', '#E55C5C', '$', 'First Aid ⛑️', 'aGhostTeam', 'mountainClimberTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('movieDirectorPostmortemTemplateWhatWereTheClimaxesAndPlotHolesInOurProjectMoviePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify key victories and hurdles.', '#DB70DB', '#', '🏔️ What were the climaxes and plot holes in our project movie?', 'aGhostTeam', 'movieDirectorPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('obstacleCoursePremortemTemplateTeamworkPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'How can we best support each other and collaborate to overcome these challenges and reach our goals?', '#DB70DB', '$', '🎽 Teamwork', 'aGhostTeam', 'obstacleCoursePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('original4Template:winsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What did we do well, that we should discuss so we don’t forget?', '#FD6157', '!', 'Wins 🏆', 'aGhostTeam', 'original4Template', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postincidentReviewTemplateWhatPreventiveMeasuresCanWePutInPlaceForSimilarIncidentsInTheFuturePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Develop strategies to minimize recurrence and enhance future responses.', '#FE975D', '$', '🛠️ What preventive measures can we put in place for similar incidents in the future?', 'aGhostTeam', 'postincidentReviewTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postmortemAnalysisTemplateWhatWorkedWellAndWhatDidntPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Highlight successes and areas that need improvement.', '#66BC8C', '#', '👍️ What worked well and what didn''t?', 'aGhostTeam', 'postmortemAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('processImprovementPostmortemTemplateWhatInnovationsOrCreativeSolutionsEmergedDuringTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify any inventive methods or ideas that proved beneficial.', '#FD6157', '#', '🔬 What innovations or creative solutions emerged during the project?', 'aGhostTeam', 'processImprovementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('questionsCommentsConcernsTemplate:concernsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What worries do you have about this proposal, decision, or idea?', '#FFCC63', '#', 'Concerns 🧐', 'aGhostTeam', 'questionsCommentsConcernsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('remoteWorkPostmortemTemplateWhatWorkedWellInOurRemoteWorkEnvironmentPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Highlight the positive aspects of your remote work dynamics.', '#66BC8C', '!', '🌍 What worked well in our remote work environment?', 'aGhostTeam', 'remoteWorkPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('resourceAllocationPremortemTemplateToolsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Are there any gaps in our toolset or technology stack that could impact the project?', '#FE975D', '$', '🛠️ Tools', 'aGhostTeam', 'resourceAllocationPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('riskManagementPostmortemTemplateHowEffectiveWereOurRiskManagementEffortsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess the success of your team''s risk mitigation strategies.', '#444258', '"', '📊 How effective were our risk management efforts?', 'aGhostTeam', 'riskManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('roseThornBudTemplate:budPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are our opportunities for growth and improvement?', '#444258', '#', 'Bud', 'aGhostTeam', 'roseThornBudTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumSprintPremortemTemplateSprintReviewPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What issues could affect our ability to showcase our progress to stakeholders?', '#DB70DB', '$', '🚀 Sprint review', 'aGhostTeam', 'scrumSprintPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumValuesRetrospectiveTemplateFocusPrompt', '2024-10-21 20:54:28.762+00', '2024-10-21 20:54:28.762+00', NULL, 'A Scrum Team''s primary focus is on the work of the Sprint to make the best possible progress toward the sprint goal. What''s helping us focus? When have we struggled to stay focused?', '#FD6157', '"', 'Focus', 'aGhostTeam', 'scrumValuesRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sixThinkingHatsTemplate:blackHatPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What was bad about the last sprint?', '#1C1C2152', '$', 'Black Hat', 'aGhostTeam', 'sixThinkingHatsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('softwareProjectPostmortemTemplateHowSmoothlyDidOurDeploymentAndMaintenanceProceduresGoPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Review the efficiency and success of your software deployment and maintenance.', '#FFCC63', '#', '🚀 How smoothly did our deployment and maintenance procedures go?', 'aGhostTeam', 'softwareProjectPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('speedCarTemplate:enginePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s helping us move faster?', '#66BC8C', '!', 'Engine', 'aGhostTeam', 'speedCarTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderConcernsPremortemTemplateTeamConcernsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What concerns might our team members have about the project?', '#8EC7F1', '"', '👩‍💼 Team concerns', 'aGhostTeam', 'stakeholderConcernsPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderSatisfactionPostmortemTemplateHowEffectiveWasOurCommunicationWithStakeholdersPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Evaluate the clarity, frequency, and impact of your communications with stakeholders.', '#FFCC63', '"', '📣 How effective was our communication with stakeholders?', 'aGhostTeam', 'stakeholderSatisfactionPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('starfishTemplate:moreOfPrompt', '2024-10-21 20:54:29.27+00', '2024-10-21 20:54:29.27+00', NULL, 'What are we not taking enough advantage of?', '#45E5E5', '#', 'More Of ➕', 'aGhostTeam', 'starfishTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatAdopt', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What new behaviors should we adopt?', '#52CC52', '!', 'Start', 'aGhostTeam', 'startStopContinueTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroPostmortemTemplateWhatOpportunitiesLieAheadForEachSuperheroPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Discuss ways to further leverage each team member''s talents.', '#DB70DB', '#', '💪 What opportunities lie ahead for each superhero?', 'aGhostTeam', 'superheroPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroRetrospectiveTemplate:gadgetsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What people, tools, or processes are most helpful?', '#DB70DB', '"', 'Gadgets', 'aGhostTeam', 'superheroRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('surprisedWorriedInspiredTemplate:worriedPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are you anxious about?', '#7272E5', '"', 'Worried', 'aGhostTeam', 'surprisedWorriedInspiredTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('newYearRetrospectiveTemplate:resolutionsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Looking ahead, how can we improve? What things can we work on or commit to for the future.', '#FFCC63', '#', 'Resolutions 🗓️', 'aGhostTeam', 'newYearRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('obstacleCoursePremortemTemplateHurdlesPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What barriers might we encounter that require us to change course or adapt our approach?', '#7272E5', '!', '🚧 Hurdles', 'aGhostTeam', 'obstacleCoursePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('original4Template:questionsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What still puzzles us?', '#8EC7F1', '$', 'Questions ❓', 'aGhostTeam', 'original4Template', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postincidentReviewTemplateWhatWereTheRootCausesAndContributingFactorsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify the underlying causes and other elements that played a role in the problems you faced.', '#7272E5', '"', '🌳 What were the root causes and contributing factors?', 'aGhostTeam', 'postincidentReviewTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postmortemAnalysisTemplateWhatCanWeLearnAndApplyToFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Create actionable plans from the insights the other questions revealed.', '#FD6157', '$', '🗒️ What can we learn and apply to future projects?', 'aGhostTeam', 'postmortemAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('processImprovementPostmortemTemplateWhatProcessesCouldBeImprovedPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Pinpoint areas where your project''s procedures faced challenges or fell short.', '#66BC8C', '"', '⚠️ What processes could be improved?', 'aGhostTeam', 'processImprovementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('remoteWorkPostmortemTemplateWhatStepsCanWeTakeToMakeRemoteWorkMoreSeamlessPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Brainstorm ways to enhance remote collaboration and streamline communication.', '#7272E5', '$', '🌐 What steps can we take to make remote work more seamless?', 'aGhostTeam', 'remoteWorkPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('resourceAllocationPremortemTemplatePeoplePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Are we lacking any essential skills or expertise for the project?', '#FFCC63', '!', '💼 People', 'aGhostTeam', 'resourceAllocationPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('riskManagementPostmortemTemplateHowCanWeImproveRiskManagementForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Define actions and procedures to enhance your team''s ability to navigate uncertainties.', '#FD6157', '$', '🔮 How can we improve risk management for future projects?', 'aGhostTeam', 'riskManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('risksAndPrecautionsPremortemTemplateRisksPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What are the biggest risks we could face during the project?', '#FD6157', '!', '💥 Risks', 'aGhostTeam', 'risksAndPrecautionsPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('roseThornBudTemplate:rosePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What went well? Which of our current practices or skills are strong?', '#FE975D', '!', 'Rose', 'aGhostTeam', 'roseThornBudTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('safariPremortemTemplateCheetahPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What issues are hidden in plain sight, ready to pounce on us?', '#444258', '#', '🐅 Cheetah', 'aGhostTeam', 'safariPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatRisks', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What risks may the team encounter ahead?', '#E55C5C', '#', 'Risks', 'aGhostTeam', 'sailboatTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('saMoLoTemplate:sameOfPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we want to keep doing?', '#FFCC63', '!', 'Same of', 'aGhostTeam', 'saMoLoTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumRolesPremortemTemplateProductOwnerPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges might the Product Owner face in managing the product backlog and aligning with stakeholders?', '#FD6157', '#', '📚 Product Owner', 'aGhostTeam', 'scrumRolesPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumSprintPremortemTemplateProductBacklogPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges could arise in maintaining a healthy and prioritized backlog?', '#7272E5', '!', '🎯 Product backlog', 'aGhostTeam', 'scrumSprintPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumValuesRetrospectiveTemplateRespectPrompt', '2024-10-21 20:54:28.762+00', '2024-10-21 20:54:28.762+00', NULL, 'Scrum Team members respect each other to be capable, independent people, and are respected as such by the people with whom they work. What practices help us practice respect and build psychological safety? Are there cases when we have struggled with this?', '#7272E5', '$', 'Respect', 'aGhostTeam', 'scrumValuesRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('simplePostmortemTemplateWhatActionsCanWeTakeToAddressTheseImprovementsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Outline actions to boost future projects.', '#FE975D', '#', '📝 What actions can we take to address these improvements?', 'aGhostTeam', 'simplePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sixThinkingHatsTemplate:blueHatPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we want to achieve in this session?', '#61B1EB', '!', 'Blue Hat', 'aGhostTeam', 'sixThinkingHatsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sixThinkingHatsTemplate:redHatPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s your overall feeling about the previous sprint?', '#D5211A', '&', 'Red Hat', 'aGhostTeam', 'sixThinkingHatsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('softwareProjectPostmortemTemplateHowSuccessfulWereOurTestingAndQualityAssuranceEffortsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Evaluate the thoroughness and accuracy of your testing and QA processes.', '#FD6157', '"', '🔎 How successful were our testing and quality assurance efforts?', 'aGhostTeam', 'softwareProjectPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('speedCarTemplate:parachutePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What’s slowing us down?', '#FD6157', '"', 'Parachute', 'aGhostTeam', 'speedCarTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderConcernsPremortemTemplateExecutiveConcernsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What concerns might our executives have about the project?', '#7272E5', '!', '🤵 Executive concerns', 'aGhostTeam', 'stakeholderConcernsPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderSatisfactionPostmortemTemplateWhatStepsCanWeTakeToImproveStakeholderEngagementInFuturePro', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Develop approaches to strengthen stakeholder relationships, improve communication, and align project outcomes with stakeholder expectations.', '#8EC7F1', '$', '🎯 What steps can we take to improve stakeholder engagement in future projects?', 'aGhostTeam', 'stakeholderSatisfactionPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('keepDoingPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What behaviors are working and adding value?', '#7373E5', '!', 'Keep Doing 🌀', 'aGhostTeam', 'starfishTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postincidentReviewTemplateWhatIncidentsOrIssuesDisruptedOurFlowPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'List the incidents that took place.', '#FFCC63', '!', '🚩 What incidents or issues disrupted our flow?', 'aGhostTeam', 'postincidentReviewTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postmortemAnalysisTemplateWhatWereOurProjectsObjectivesAndDidWeAchieveThemPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Re-examine your project goals and evaluate your performance against them.', '#DB70DB', '!', '🎯 What were our project''s objectives, and did we achieve them?', 'aGhostTeam', 'postmortemAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('processImprovementPostmortemTemplateHowCanWeOptimizeOurWorkflowsForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Develop strategies to enhance processes and adopt or update best practices.', '#FFCC63', '$', '📝 How can we optimize our workflows for future projects?', 'aGhostTeam', 'processImprovementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('questionsCommentsConcernsTemplate:questionsPrompt-2', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What isn’t clear about this proposal, decision, or idea? What needs further explanation?', '#66BC8C', '!', 'Questions ❓', 'aGhostTeam', 'questionsCommentsConcernsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('remoteWorkPostmortemTemplateWhatSpecificRemoteWorkChallengesDidWeFacePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Pinpoint the unique obstacles that emerged due to the distributed work setup.', '#FFCC63', '#', '💻 What specific remote work challenges did we face?', 'aGhostTeam', 'remoteWorkPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('resourceAllocationPremortemTemplateTimePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Are there any time constraints or scheduling conflicts that could hinder the project?', '#7272E5', '"', '⏳ Time', 'aGhostTeam', 'resourceAllocationPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('riskManagementPostmortemTemplateWhatUnexpectedRisksOrChallengesEmergedPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Explore unforeseen risks and their impact on the project.', '#66BC8C', '#', '🚧 What unexpected risks or challenges emerged?', 'aGhostTeam', 'riskManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('risksAndPrecautionsPremortemTemplatePrecautionsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What precautions should we take now to mitigate these risks?', '#FFCC63', '"', '⛑️ Precautions', 'aGhostTeam', 'risksAndPrecautionsPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('roseThornBudTemplate:thornPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What challenges or difficulties did we run into?', '#DB70DB', '"', 'Thorn', 'aGhostTeam', 'roseThornBudTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('safariPremortemTemplateElephantPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What concerns you that nobody else is discussing?', '#DB70DB', '"', '🐘 Elephant', 'aGhostTeam', 'safariPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatSlowing', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What’s slowing the team down in your journey?', '#D9D916', '"', 'Anchors', 'aGhostTeam', 'sailboatTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('saMoLoTemplate:moreOfPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we want to do more of?', '#7272E5', '"', 'More of', 'aGhostTeam', 'saMoLoTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumRolesPremortemTemplateDevelopersPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges might the developers face in executing the project?', '#66BC8C', '"', '👨‍💻 Developers', 'aGhostTeam', 'scrumRolesPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumSprintPremortemTemplateSprintPlanningPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What obstacles might we face in effectively planning and executing sprints?', '#8EC7F1', '"', '📊 Sprint planning', 'aGhostTeam', 'scrumSprintPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumValuesRetrospectiveTemplateCommitmentPrompt', '2024-10-21 20:54:28.762+00', '2024-10-21 20:54:28.762+00', NULL, 'Scrum Teams are committed to achieving their goals and to supporting each other. What are some examples of us doing this well? In what cases have we struggled or failed to be committed?', '#66BC8C', '!', 'Commitment', 'aGhostTeam', 'scrumValuesRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sixThinkingHatsTemplate:greenHatPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What things could improve for our next sprint?', '#66BC8C', '%', 'Green Hat', 'aGhostTeam', 'sixThinkingHatsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('softwareProjectPostmortemTemplateHowDidOurDevelopmentProcessPerformDuringTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess the effectiveness and efficiency of your software development process.', '#66BC8C', '!', '👩‍💻 How did our development process perform during the project?', 'aGhostTeam', 'softwareProjectPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderConcernsPremortemTemplateClientConcernsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What concerns might our clients have about the project?', '#FE975D', '#', '🤝 Client concerns', 'aGhostTeam', 'stakeholderConcernsPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderSatisfactionPostmortemTemplateHowAlignedWereOurProjectOutcomesWithStakeholderExpectations', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess the alignment between your team''s deliverables and stakeholder expectations.', '#FD6157', '!', '🤝 How aligned were our project outcomes with stakeholder expectations?', 'aGhostTeam', 'stakeholderSatisfactionPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stopPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What isn''t adding value or helping the team?', '#E55C5C', '$', 'Stop ⏹️', 'aGhostTeam', 'starfishTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatCease', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What existing behaviors should we cease doing?', '#E55C5C', '"', 'Stop', 'aGhostTeam', 'startStopContinueTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('successAndFailurePremortemTemplateWhatDoesFailureLookLikePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Consider the potential obstacles and challenges that could derail the project.', '#DB70DB', '"', '🚧 What does failure look like?', 'aGhostTeam', 'successAndFailurePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroPostmortemTemplateWhatUniqueSuperpowersDoesEachTeamMemberPossessPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Discover the unique talents of each individual.', '#8EC7F1', '!', '🦸 What unique superpowers does each team member possess?', 'aGhostTeam', 'superheroPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroRetrospectiveTemplate:rolePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Where do you fit into the team? How do you see your role interacting with others?', '#66BC8C', '$', 'Role', 'aGhostTeam', 'superheroRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('surprisedWorriedInspiredTemplate:surprisedPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What caught you off guard, positively or negatively?', '#FFCC63', '!', 'Surprised', 'aGhostTeam', 'surprisedWorriedInspiredTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sWOTAnalysisTemplate:weaknessesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What needs more work?', '#DB70DB', '"', 'Weaknesses', 'aGhostTeam', 'sWOTAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamCharterTemplateAchievementsPrompt', '2024-10-21 20:54:28.76+00', '2024-10-21 20:54:28.76+00', NULL, 'What are we setting out to achieve together? What differentiates us? How do we measure success?', '#FFCC63', '#', 'Achievements', 'aGhostTeam', 'teamCharterTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamEfficiencyPremortemTemplateWhereCouldWeGetStuckPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Anticipate potential bottlenecks or obstacles that may stall the project.', '#66BC8C', '"', '🚧 Where could we get stuck?', 'aGhostTeam', 'teamEfficiencyPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamPerformancePostmortemTemplateHowCanWeImproveCollaborationForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Determine areas for growth and develop strategies to enhance teamwork.', '#8EC7F1', '#', '🤝 How can we improve collaboration for future projects?', 'aGhostTeam', 'teamPerformancePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamRetreatPlanningTemplate:fearsPrompt-2', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What concerns do you have about the retreat? What are you worried about?', '#8EC7F1', '"', 'Fears 🧟', 'aGhostTeam', 'teamRetreatPlanningTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('thanksgivingRetrospectiveTemplate:leftOnTheTablePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we wish we’d left behind, or should leave behind from now on?', '#DB70DB', '#', 'Left on the Table 🐌', 'aGhostTeam', 'thanksgivingRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('postmortemAnalysisTemplateWhatChallengesOrObstaclesDidWeFacePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify the challenges that shaped your project.', '#444258', '"', '📉 What challenges or obstacles did we face?', 'aGhostTeam', 'postmortemAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('processImprovementPostmortemTemplateWhatProcessesWorkedWellDuringTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Find the successful aspects of your project''s workflows and methodologies.', '#444258', '!', '🔄 What processes worked well during the project?', 'aGhostTeam', 'processImprovementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('questionsCommentsConcernsTemplate:commentsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What reactions do you have to this proposal, decision, or idea?', '#FD6157', '"', 'Comments 💬', 'aGhostTeam', 'questionsCommentsConcernsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('remoteWorkPostmortemTemplateWhereDidOurDigitalCommunicationFallFlatPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify areas where remote communication could be improved.', '#FD6157', '"', '📞 Where did our digital communication fall flat?', 'aGhostTeam', 'remoteWorkPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('resourceAllocationPremortemTemplateBudgetPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Are there any budget limitations or financial risks that could impact the project?', '#8EC7F1', '#', '💰 Budget', 'aGhostTeam', 'resourceAllocationPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('riskManagementPostmortemTemplateWhatRisksDidWeIdentifyAndHowDidWeManageThemPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Review the identified risks and your team''s risk mitigation strategies.', '#DB70DB', '!', '🎲 What risks did we identify, and how did we manage them?', 'aGhostTeam', 'riskManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('safariPremortemTemplateMonkeyPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What early warning signs could indicate something is going wrong?', '#66BC8C', '$', '🐒 Monkey', 'aGhostTeam', 'safariPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatHelpGoal', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What’s helping the team reach its goals?', '#52CC52', '!', 'Wind in the sails', 'aGhostTeam', 'sailboatTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('saMoLoTemplate:lessOfPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do we want to do less of?', '#8EC7F1', '#', 'Less of', 'aGhostTeam', 'saMoLoTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumRolesPremortemTemplateScrumMasterPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges might the Scrum Master face in facilitating the project?', '#444258', '!', '🏃 Scrum Master', 'aGhostTeam', 'scrumRolesPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumSprintPremortemTemplateRetrospectivesPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges could impact the effectiveness of our retrospectives and continuous improvement efforts?', '#FE975D', '#', '🔄 Retrospectives', 'aGhostTeam', 'scrumSprintPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumValuesRetrospectiveTemplateOpennessPrompt', '2024-10-21 20:54:28.762+00', '2024-10-21 20:54:28.762+00', NULL, 'Scrum Teams are open about their work and the challenges they face. How could we improve transparency in our work? What practices are helping us be more open about our work?', '#FFCC63', '#', 'Openness', 'aGhostTeam', 'scrumValuesRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('simplePostmortemTemplateWhatCouldBeImprovedForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify the project’s challenges and issues.', '#8EC7F1', '"', '❌ What could be improved for future projects?', 'aGhostTeam', 'simplePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sixThinkingHatsTemplate:yellowHatPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What was good about the last sprint?', '#FFCC63', '#', 'Yellow Hat', 'aGhostTeam', 'sixThinkingHatsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderConcernsPremortemTemplateCommunityConcernsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What concerns might the broader community have about the project?', '#DB70DB', '$', '🌐 Community concerns', 'aGhostTeam', 'stakeholderConcernsPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('stakeholderSatisfactionPostmortemTemplateWhatChallengesDidWeEncounterInManagingStakeholderExpectatio', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify any misunderstandings or disconnects that arose between the team and stakeholders.', '#7272E5', '#', '🚩 What challenges did we encounter in managing stakeholder expectations?', 'aGhostTeam', 'stakeholderSatisfactionPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('starfishTemplate:lessOfPrompt', '2024-10-21 20:54:29.27+00', '2024-10-21 20:54:29.27+00', NULL, 'What are we over-doing or doing too much of?', '#D9D916', '"', 'Less Of ➖', 'aGhostTeam', 'starfishTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroPostmortemTemplateHowCanWeBetterAlignOurSuperpowersWithProjectObjectivesPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Consider how to match individual strengths with specific project goals.', '#444258', '$', '🎯 How can we better align our superpowers with project objectives?', 'aGhostTeam', 'superheroPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroRetrospectiveTemplate:superpowerPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are your strongest skills?', '#FE975D', '!', 'Superpower', 'aGhostTeam', 'superheroRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sWOTAnalysisTemplate:threatsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What could be negative or dangerous to us?', '#66BC8C', '$', 'Threats', 'aGhostTeam', 'sWOTAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamCharterTemplateMissionPrompt', '2024-10-21 20:54:28.76+00', '2024-10-21 20:54:28.76+00', NULL, 'What''s the overall mission of our team?', '#66BC8C', '!', 'Mission', 'aGhostTeam', 'teamCharterTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamEfficiencyPremortemTemplateWhatCausedUsToMissTheDeadlinePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Envision scenarios that could lead to missed deadlines and develop strategies to avoid them.', '#FFCC63', '$', '🎯 What caused us to miss the deadline?', 'aGhostTeam', 'teamEfficiencyPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamPerformancePostmortemTemplateWhatCommunicationChallengesDidWeFacePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify any communication issues that arose and their impact on the project.', '#7272E5', '"', '🗣️ What communication challenges did we face?', 'aGhostTeam', 'teamPerformancePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamRetreatPlanningTemplate:hopesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What do you hope we will do together? What do you hope will come from our time together?', '#7272E5', '!', 'Hopes 🙏', 'aGhostTeam', 'teamRetreatPlanningTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('thanksgivingRetrospectiveTemplate:newTraditionsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What new things did we try or learn?', '#FE975D', '"', 'New Traditions 🍟', 'aGhostTeam', 'thanksgivingRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('threatLevelPremortemTemplateLowPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What low-risk issues should we expect? (Max. 5 minutes of discussion during the pre-mortem)', '#66BC8C', '#', '🟢 Low', 'aGhostTeam', 'threatLevelPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptHouseOfSticks', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What needs more work?', '#D5211A', '"', 'House of Sticks', 'aGhostTeam', 'threeLittlePigsTemplate', 'promptWhatCease'); +INSERT INTO public."ReflectPrompt" VALUES ('timelinePremortemTemplateMiddlePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges might we face during the middle of the project? Reflect on possible hurdles like shifting deadlines, team fatigue, and evolving priorities.', '#66BC8C', '"', '🕰️ Middle', 'aGhostTeam', 'timelinePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeManagementPostmortemTemplateHowAccurateWereOurInitialTimeEstimatesPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Gauge the precision of your team''s time forecasts and compare them to the actual time invested in project tasks.', '#FD6157', '!', '⏱️ How accurate were our initial time estimates?', 'aGhostTeam', 'timeManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeTravelPostmortemTemplateHowWillChangesWeMakeNowImproveFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Consider how actions you take now will play out in future projects.', '#7272E5', '$', '🌈 How will changes we make now improve future projects?', 'aGhostTeam', 'timeTravelPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('uncertainWatersPremortemTemplateHiddenReefsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What unforeseen obstacles or issues could cause us to run aground?', '#8EC7F1', '!', '🌊 Hidden reefs', 'aGhostTeam', 'uncertainWatersPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('scrumValuesRetrospectiveTemplateCouragePrompt', '2024-10-21 20:54:28.762+00', '2024-10-21 20:54:28.762+00', NULL, 'Scrum Teams have the courage to do the right thing and to work on tough problems. Are there any times when we struggled to be courageous or didn''t do the right thing?', '#8EC7F1', '%', 'Courage', 'aGhostTeam', 'scrumValuesRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('simplePostmortemTemplateWhatWentWellDuringTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Highlight the successful aspects of the project.', '#7272E5', '!', '✅ What went well during the project?', 'aGhostTeam', 'simplePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sixThinkingHatsTemplate:whiteHatPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are the facts or information we have about the last sprint?', '#F8F7FC', '"', 'White Hat', 'aGhostTeam', 'sixThinkingHatsTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('startPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What new things should we explore or start doing?', '#52CC52', '%', 'Start ⏯️', 'aGhostTeam', 'starfishTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatKeep', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What current behaviors should we keep doing?', '#D9D916', '#', 'Continue', 'aGhostTeam', 'startStopContinueTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('successAndFailurePremortemTemplateWhatDoesSuccessLookLikePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Envision the end goal and the milestones that mark the path to success.', '#FE975D', '!', '🏆 What does success look like?', 'aGhostTeam', 'successAndFailurePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroPostmortemTemplateHowDidTheseSuperpowersDriveTheProjectForwardPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Analyze how individual strengths influenced the project''s outcome.', '#FE975D', '"', '💥 How did these superpowers drive the project forward?', 'aGhostTeam', 'superheroPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('superheroRetrospectiveTemplate:nemesisPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What makes your role more difficult?', '#444258', '#', 'Nemesis', 'aGhostTeam', 'superheroRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('surprisedWorriedInspiredTemplate:inspiredPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What has you energized for the future?', '#8EC7F1', '#', 'Inspired', 'aGhostTeam', 'surprisedWorriedInspiredTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('sWOTAnalysisTemplate:stengthsPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are we good at?', '#FE975D', '!', 'Strengths', 'aGhostTeam', 'sWOTAnalysisTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamCharterTemplateResponsibilitiesPrompt', '2024-10-21 20:54:28.76+00', '2024-10-21 20:54:28.76+00', NULL, 'What is our team responsible for?', '#7272E5', '$', 'Responsibilities', 'aGhostTeam', 'teamCharterTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamEfficiencyPremortemTemplateWhatSlowedUsDownPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify processes or factors that could hinder your team''s progress.', '#444258', '!', '⏳ What slowed us down?', 'aGhostTeam', 'teamEfficiencyPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('thanksgivingRetrospectiveTemplate:gratitudePrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are you thankful for?', '#444258', '$', 'Gratitude 🍰', 'aGhostTeam', 'thanksgivingRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('threatLevelPremortemTemplateElevatedPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What moderate issues would we run into that delay the project? (Warrants 10-20 minutes of discussion during the pre-mortem.)', '#FFCC63', '"', '🟡 Elevated', 'aGhostTeam', 'threatLevelPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptHouseOfBricks', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What is rock solid and working well?', '#66BC8C', '#', 'House of Bricks', 'aGhostTeam', 'threeLittlePigsTemplate', 'promptWhatKeep'); +INSERT INTO public."ReflectPrompt" VALUES ('timelinePremortemTemplateStartPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges might we face at the beginning of the project? Consider potential obstacles such as team formation, initial planning, and resource allocation.', '#444258', '!', '📆 Start', 'aGhostTeam', 'timelinePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeManagementPostmortemTemplateWhatObstaclesImpactedOurTimeManagementPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Uncover the factors that caused delays or inefficiencies in the project and learn from them.', '#7272E5', '#', '🚧 What obstacles impacted our time management?', 'aGhostTeam', 'timeManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeTravelPostmortemTemplateIfWeCouldGoBackInTimeWhatWouldWeChangePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Discuss changes your team would make if given a second chance.', '#66BC8C', '!', '⌛ If we could go back in time, what would we change?', 'aGhostTeam', 'timeTravelPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('uncertainWatersPremortemTemplateSafeHarborsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'How can we best prepare to weather these challenges and uncertainties?', '#444258', '$', '🏝️ Safe harbors', 'aGhostTeam', 'uncertainWatersPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('whatIfPremortemTemplateWhatIfInsertRiskPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Customize this question to address a specific risk.', '#FE975D', '!', 'What if [insert risk]', 'aGhostTeam', 'whatIfPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptRepeatingOurSuccess', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'How can we maintain/replicate our success in future?', '#E55CA0', '#', 'Repeating our success', 'aGhostTeam', 'winningStreakTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('wRAPTemplate:appreciationPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'Who made this sprint special or did exceptional work?', '#8EC7F1', '#', 'Appreciation', 'aGhostTeam', 'wRAPTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamEfficiencyPremortemTemplateWhereMightWeNeedExtraHelpPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Recognize areas where your team may require additional resources or expertise.', '#FD6157', '#', '🆘 Where might we need extra help?', 'aGhostTeam', 'teamEfficiencyPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamPerformancePostmortemTemplateHowDidOurTeamDynamicsImpactTheProjectPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Assess the effect of your team''s interpersonal relationships on the project.', '#FFCC63', '!', '👥 How did our team dynamics impact the project?', 'aGhostTeam', 'teamPerformancePostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('teamRetreatPlanningTemplate:projectProblemPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What project should we explore? What problem should we tackle together?', '#FE975D', '#', 'Project/Problem 💡', 'aGhostTeam', 'teamRetreatPlanningTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('thanksgivingRetrospectiveTemplate:oldFavoritesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What tried-and-true practices or habits are serving us well?', '#8EC7F1', '!', 'Old Favorites 🦃', 'aGhostTeam', 'thanksgivingRetrospectiveTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeManagementPostmortemTemplateWhatStrategiesCanWeImplementToImproveTimeManagementInFutureProjectsP', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Develop action plans to master time allocation and scheduling, boosting your team''s productivity and punctuality.', '#8EC7F1', '$', '⚙️ What strategies can we implement to improve time management in future projects?', 'aGhostTeam', 'timeManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeTravelPostmortemTemplateWhatDidWeLearnForFutureProjectsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Imagine how the lessons and insights gained from this project will improve future endeavors.', '#FD6157', '"', '🚀 What did we learn for future projects?', 'aGhostTeam', 'timeTravelPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('uncertainWatersPremortemTemplateAnchorsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What might hold us back, slow our progress, or hinder our efficiency?', '#DB70DB', '#', '⚓ Anchors', 'aGhostTeam', 'uncertainWatersPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('whatIfPremortemTemplateWhatIfInsertChallengePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Adapt this question to tackle another unique challenge.', '#DB70DB', '"', 'What if [insert challenge]', 'aGhostTeam', 'whatIfPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('whatWentWellPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What good things happened this sprint?', '#7373E5', '!', 'What went well 😄', 'aGhostTeam', 'whatWentWellTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('whyDidTheProjectFailPremortemTemplateWhyDidTheProjectFailPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What could go wrong and prevent us meeting our goals? Try to focus on things that could reasonably put the project off track. ', '#8EC7F1', '!', '⁉️ Why did the project fail?', 'aGhostTeam', 'whyDidTheProjectFailPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptBigWins', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What are we proud of achieving?', '#52CC52', '!', 'Big wins', 'aGhostTeam', 'winningStreakTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatBlocking', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What’s blocking us from achieving our goals?', '#E55C5C', '"', 'Where did you get stuck?', 'aGhostTeam', 'workingStuckTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('wRAPTemplate:risksPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What risks or challenges lie ahead? What was risky about our work in the last period?', '#7272E5', '"', 'Risks', 'aGhostTeam', 'wRAPTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('threatLevelPremortemTemplateSeverePrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What severe issues could we run into that derail the project? (Requires a separate meeting or review.)', '#FD6157', '!', '🔴 Severe', 'aGhostTeam', 'threatLevelPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptHouseOfStraw', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What is at risk of breaking?', '#FFCC63', '!', 'House of Straw', 'aGhostTeam', 'threeLittlePigsTemplate', 'promptWhatAdopt'); +INSERT INTO public."ReflectPrompt" VALUES ('timelinePremortemTemplateEndPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What challenges might we face at the end of the project? Envision potential difficulties like last-minute changes, finalizing deliverables, and closing the project effectively.', '#FD6157', '#', '🏁 End', 'aGhostTeam', 'timelinePremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeManagementPostmortemTemplateWhichTasksTookLongerThanExpectedAndWhyPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Identify tasks that required more time than anticipated and discuss the reasons behind this.', '#FFCC63', '"', '📅 Which tasks took longer than expected, and why?', 'aGhostTeam', 'timeManagementPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('timeTravelPostmortemTemplateHowDidThisProjectShapeOurTeamsGrowthAndDevelopmentPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Imagine how this project impacts your team''s evolution.', '#FFCC63', '#', '🔍 How did this project shape our team''s growth and development?', 'aGhostTeam', 'timeTravelPostmortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('uncertainWatersPremortemTemplateStormsPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'What significant challenges or crises might we face during the project?', '#FE975D', '"', '🌀 Storms', 'aGhostTeam', 'uncertainWatersPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('whatIfPremortemTemplateWhatIfInsertConcernPrompt', '2024-10-21 20:55:10.872+00', '2024-10-21 20:55:10.872+00', NULL, 'Tailor this question to explore an additional concern.', '#444258', '#', 'What if [insert concern]', 'aGhostTeam', 'whatIfPremortemTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('whatDidntGoWellPrompt', '2024-10-21 20:53:55.206+00', '2024-10-21 20:53:55.206+00', NULL, 'What didn''t go as planned or desired this sprint?', '#E55C5C', '"', 'What didn''t go well 😞', 'aGhostTeam', 'whatWentWellTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptTeamwork', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'What teamwork practices helped us reach our goals?', '#AC73E5', '"', 'Teamwork', 'aGhostTeam', 'winningStreakTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('wRAPTemplate:puzzlesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What unresolved questions do you have?', '#FE975D', '$', 'Puzzles', 'aGhostTeam', 'wRAPTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptKudos', '2024-10-21 20:53:55.199+00', '2024-10-21 20:53:55.199+00', NULL, 'Share the love! Give a shoutout to someone who did great work!', '#45E5E5', '$', 'Kudos', 'aGhostTeam', 'winningStreakTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('promptWhatHelps', '2016-06-01 00:00:00+00', '2016-06-01 00:00:00+00', NULL, 'What’s helping us make progress toward our goals?', '#52CC52', '!', 'What’s working?', 'aGhostTeam', 'workingStuckTemplate', NULL); +INSERT INTO public."ReflectPrompt" VALUES ('wRAPTemplate:wishesPrompt', '2022-01-28 00:00:00+00', '2024-10-21 20:54:28.757+00', NULL, 'What are your wishes for the team or your work? What would make work better?', '#FFCC63', '!', 'Wishes', 'aGhostTeam', 'wRAPTemplate', NULL); + + +-- +-- TOC entry 4479 (class 0 OID 2494877) +-- Dependencies: 275 +-- Data for Name: RetroReflection; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4466 (class 0 OID 2494277) +-- Dependencies: 261 +-- Data for Name: RetroReflectionGroup; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4468 (class 0 OID 2494320) +-- Dependencies: 263 +-- Data for Name: SAML; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4469 (class 0 OID 2494339) +-- Dependencies: 264 +-- Data for Name: SAMLDomain; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4478 (class 0 OID 2494462) +-- Dependencies: 273 +-- Data for Name: ScheduledJob; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4496 (class 0 OID 2495243) +-- Dependencies: 293 +-- Data for Name: SlackAuth; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4497 (class 0 OID 2495281) +-- Dependencies: 294 +-- Data for Name: SlackNotification; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4442 (class 0 OID 2493936) +-- Dependencies: 236 +-- Data for Name: StripeQuantityMismatchLogging; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4491 (class 0 OID 2495123) +-- Dependencies: 288 +-- Data for Name: SuggestedAction; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4512 (class 0 OID 2495607) +-- Dependencies: 309 +-- Data for Name: Task; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4434 (class 0 OID 2493876) +-- Dependencies: 228 +-- Data for Name: TaskEstimate; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4430 (class 0 OID 2493815) +-- Dependencies: 224 +-- Data for Name: Team; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."Team" VALUES ('aGhostTeam', 'Parabol', '2016-06-01 00:00:00+00', 'aGhostUser', false, true, '{}', 'retrospective', 'enterprise', 'aGhostOrg', true, '2024-10-21 20:55:52.678+00', NULL, 0, false, NULL, '❤️'); + + +-- +-- TOC entry 4511 (class 0 OID 2495559) +-- Dependencies: 308 +-- Data for Name: TeamInvitation; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4467 (class 0 OID 2494303) +-- Dependencies: 262 +-- Data for Name: TeamMeetingTemplate; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4483 (class 0 OID 2494997) +-- Dependencies: 280 +-- Data for Name: TeamMember; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4445 (class 0 OID 2494008) +-- Dependencies: 239 +-- Data for Name: TeamMemberIntegrationAuth; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4447 (class 0 OID 2494046) +-- Dependencies: 242 +-- Data for Name: TeamPromptResponse; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4488 (class 0 OID 2495066) +-- Dependencies: 285 +-- Data for Name: TemplateDimension; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."TemplateDimension" VALUES ('eeStoryPointsDimension', '2024-10-21 20:53:55.201+00', 'Story Points', '', 'aGhostTeam', '2024-10-21 20:53:55.201+00', 'estimatedEffortTemplate', 'fibonacciScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('moscowPriorityDimension', '2024-10-21 20:55:19.897+00', 'Priority? Must/Should/Could/Won’t Have', '', 'aGhostTeam', '2024-10-21 20:55:19.897+00', 'moscowPrioritizationTemplate', 'moscowScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('wsjfStoryPointsDimension', '2024-10-21 20:53:55.201+00', 'Story Points', '', 'aGhostTeam', '2024-10-21 20:53:55.201+00', 'wsjfTemplate', 'fibonacciScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('riceReachDimension', '2024-10-21 20:55:19.897+00', 'Reach', '', 'aGhostTeam', '2024-10-21 20:55:19.897+00', 'ricePrioritizationTemplate', 'fiveFingersScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('riceImpactDimension', '2024-10-21 20:55:19.897+00', 'Impact', '', 'aGhostTeam', '2024-10-21 20:55:19.897+00', 'ricePrioritizationTemplate', 'fiveFingersScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('wsjfStoryValueDimension', '2024-10-21 20:53:55.201+00', 'Story Value', '', 'aGhostTeam', '2024-10-21 20:53:55.201+00', 'wsjfTemplate', 'fibonacciScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('riceConfidenceDimension', '2024-10-21 20:55:19.897+00', 'Confidence', '', 'aGhostTeam', '2024-10-21 20:55:19.897+00', 'ricePrioritizationTemplate', 'fiveFingersScale', '"', NULL); +INSERT INTO public."TemplateDimension" VALUES ('riceEffortDimension', '2024-10-21 20:55:19.897+00', 'Effort', '', 'aGhostTeam', '2024-10-21 20:55:19.897+00', 'ricePrioritizationTemplate', 'fiveFingersScale', '"', NULL); + + +-- +-- TOC entry 4427 (class 0 OID 2493656) +-- Dependencies: 221 +-- Data for Name: TemplateRef; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4485 (class 0 OID 2495030) +-- Dependencies: 282 +-- Data for Name: TemplateScale; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."TemplateScale" VALUES ('tshirtSizeScale', '2024-10-21 20:53:55.202+00', 'T-Shirt Sizes', 'aGhostTeam', '2024-10-21 20:55:54.606965+00', NULL, true, NULL); +INSERT INTO public."TemplateScale" VALUES ('priorityScale', '2024-10-21 20:53:55.205+00', 'Priorities', 'aGhostTeam', '2024-10-21 20:55:54.606965+00', NULL, true, NULL); +INSERT INTO public."TemplateScale" VALUES ('moscowScale', '2024-10-21 20:55:19.897+00', 'MoSCoW', 'aGhostTeam', '2024-10-21 20:55:54.606965+00', NULL, true, NULL); +INSERT INTO public."TemplateScale" VALUES ('fibonacciScale', '2024-10-21 20:53:55.202+00', 'Fibonacci', 'aGhostTeam', '2024-10-21 20:55:54.606965+00', NULL, true, NULL); +INSERT INTO public."TemplateScale" VALUES ('fiveFingersScale', '2024-10-21 20:53:55.202+00', 'Five Fingers', 'aGhostTeam', '2024-10-21 20:55:54.606965+00', NULL, true, NULL); + + +-- +-- TOC entry 4426 (class 0 OID 2493648) +-- Dependencies: 220 +-- Data for Name: TemplateScaleRef; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4487 (class 0 OID 2495046) +-- Dependencies: 284 +-- Data for Name: TemplateScaleValue; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."TemplateScaleValue" VALUES (1, 'tshirtSizeScale', '!', '#5CA0E5', 'XS'); +INSERT INTO public."TemplateScaleValue" VALUES (2, 'tshirtSizeScale', '"', '#5CA0E5', 'SM'); +INSERT INTO public."TemplateScaleValue" VALUES (3, 'tshirtSizeScale', '#', '#45E595', 'M'); +INSERT INTO public."TemplateScaleValue" VALUES (4, 'tshirtSizeScale', '$', '#E59545', 'L'); +INSERT INTO public."TemplateScaleValue" VALUES (5, 'tshirtSizeScale', '%', '#E59545', 'XL'); +INSERT INTO public."TemplateScaleValue" VALUES (6, 'tshirtSizeScale', '&', '#E55CA0', '?'); +INSERT INTO public."TemplateScaleValue" VALUES (7, 'tshirtSizeScale', '''', '#AC72E5', 'Pass'); +INSERT INTO public."TemplateScaleValue" VALUES (8, 'priorityScale', '!', '#DB70DB', '?'); +INSERT INTO public."TemplateScaleValue" VALUES (9, 'priorityScale', '"', '#329AE5', 'P0'); +INSERT INTO public."TemplateScaleValue" VALUES (10, 'priorityScale', '#', '#329AE5', 'P1'); +INSERT INTO public."TemplateScaleValue" VALUES (11, 'priorityScale', '$', '#66BC8C', 'P2'); +INSERT INTO public."TemplateScaleValue" VALUES (12, 'priorityScale', '%', '#66BC8C', 'P3'); +INSERT INTO public."TemplateScaleValue" VALUES (13, 'priorityScale', '&', '#FE975D', 'P4'); +INSERT INTO public."TemplateScaleValue" VALUES (14, 'priorityScale', '''', '#FE975D', 'P5'); +INSERT INTO public."TemplateScaleValue" VALUES (15, 'priorityScale', '(', '#A06BD6', 'Pass'); +INSERT INTO public."TemplateScaleValue" VALUES (16, 'moscowScale', '!', '#FD6157', 'M'); +INSERT INTO public."TemplateScaleValue" VALUES (17, 'moscowScale', '"', '#FE975D', 'S'); +INSERT INTO public."TemplateScaleValue" VALUES (18, 'moscowScale', '#', '#FFCC63', 'C'); +INSERT INTO public."TemplateScaleValue" VALUES (19, 'moscowScale', '$', '#C4CF66', 'W'); +INSERT INTO public."TemplateScaleValue" VALUES (20, 'moscowScale', '%', '#ED4C86', '?'); +INSERT INTO public."TemplateScaleValue" VALUES (21, 'moscowScale', '&', '#A06BD6', 'Pass'); +INSERT INTO public."TemplateScaleValue" VALUES (22, 'fibonacciScale', '!', '#5CA0E5', '1'); +INSERT INTO public."TemplateScaleValue" VALUES (23, 'fibonacciScale', '"', '#5CA0E5', '2'); +INSERT INTO public."TemplateScaleValue" VALUES (24, 'fibonacciScale', '#', '#45E595', '3'); +INSERT INTO public."TemplateScaleValue" VALUES (25, 'fibonacciScale', '$', '#45E595', '5'); +INSERT INTO public."TemplateScaleValue" VALUES (26, 'fibonacciScale', '%', '#45E595', '8'); +INSERT INTO public."TemplateScaleValue" VALUES (27, 'fibonacciScale', '&', '#E59545', '13'); +INSERT INTO public."TemplateScaleValue" VALUES (28, 'fibonacciScale', '''', '#E59545', '21'); +INSERT INTO public."TemplateScaleValue" VALUES (29, 'fibonacciScale', '(', '#E59545', '34'); +INSERT INTO public."TemplateScaleValue" VALUES (30, 'fibonacciScale', ')', '#E55CA0', '?'); +INSERT INTO public."TemplateScaleValue" VALUES (31, 'fibonacciScale', '*', '#AC72E5', 'Pass'); +INSERT INTO public."TemplateScaleValue" VALUES (32, 'fiveFingersScale', '!', '#5CA0E5', '1'); +INSERT INTO public."TemplateScaleValue" VALUES (33, 'fiveFingersScale', '"', '#5CA0E5', '2'); +INSERT INTO public."TemplateScaleValue" VALUES (34, 'fiveFingersScale', '#', '#45E595', '3'); +INSERT INTO public."TemplateScaleValue" VALUES (35, 'fiveFingersScale', '$', '#E59545', '4'); +INSERT INTO public."TemplateScaleValue" VALUES (36, 'fiveFingersScale', '%', '#E59545', '5'); +INSERT INTO public."TemplateScaleValue" VALUES (37, 'fiveFingersScale', '&', '#E55CA0', '?'); +INSERT INTO public."TemplateScaleValue" VALUES (38, 'fiveFingersScale', '''', '#AC72E5', 'Pass'); + + +-- +-- TOC entry 4480 (class 0 OID 2494923) +-- Dependencies: 276 +-- Data for Name: TimelineEvent; Type: TABLE DATA; Schema: public; Owner: - +-- + + + +-- +-- TOC entry 4429 (class 0 OID 2493788) +-- Dependencies: 223 +-- Data for Name: User; Type: TABLE DATA; Schema: public; Owner: - +-- + +INSERT INTO public."User" VALUES ('aGhostUser', 'love@parabol.co', '2016-06-01 00:00:00+00', '2024-10-21 20:55:55.595498+00', false, '2016-06-01 00:00:00+00', 'A Ghost', 'enterprise', 'https://action-files.parabol.co/production/build/v5.10.1/42342faa774f05b7626fa91ff8374e59.svg', '{aGhostTeam}', '{}', '{}', '{}', NULL, NULL, NULL, false, NULL, NULL, 0, false, DEFAULT, true, true, NULL, 2, 2, '{}'); +INSERT INTO public."User" VALUES ('parabolAIUser', 'ai-user@parabol.co', '2024-10-21 20:55:52.969962+00', '2024-10-21 20:55:55.595498+00', false, '2024-10-21 20:55:52.969962+00', 'Parabol AI', 'starter', 'https://action-files.parabol.co/static/favicon-with-more-padding.jpeg', '{}', '{}', '{}', NULL, NULL, NULL, NULL, false, NULL, NULL, 0, false, DEFAULT, true, false, NULL, 2, 2, '{}'); + + +-- +-- TOC entry 4530 (class 0 OID 0) +-- Dependencies: 245 +-- Name: AzureDevOpsDimensionFieldMap_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."AzureDevOpsDimensionFieldMap_id_seq"', 1, false); + + +-- +-- TOC entry 4531 (class 0 OID 0) +-- Dependencies: 259 +-- Name: DomainJoinRequest_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."DomainJoinRequest_id_seq"', 1, false); + + +-- +-- TOC entry 4532 (class 0 OID 0) +-- Dependencies: 286 +-- Name: EmailVerification_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."EmailVerification_id_seq"', 1, false); + + +-- +-- TOC entry 4533 (class 0 OID 0) +-- Dependencies: 268 +-- Name: EmbeddingsJobQueue_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."EmbeddingsJobQueue_id_seq"', 1, false); + + +-- +-- TOC entry 4534 (class 0 OID 0) +-- Dependencies: 266 +-- Name: EmbeddingsMetadata_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."EmbeddingsMetadata_id_seq"', 99, true); + + +-- +-- TOC entry 4535 (class 0 OID 0) +-- Dependencies: 270 +-- Name: FailedAuthRequest_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."FailedAuthRequest_id_seq"', 1, false); + + +-- +-- TOC entry 4536 (class 0 OID 0) +-- Dependencies: 233 +-- Name: GitHubDimensionFieldMap_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."GitHubDimensionFieldMap_id_seq"', 1, false); + + +-- +-- TOC entry 4537 (class 0 OID 0) +-- Dependencies: 243 +-- Name: GitLabDimensionFieldMap_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."GitLabDimensionFieldMap_id_seq"', 1, false); + + +-- +-- TOC entry 4538 (class 0 OID 0) +-- Dependencies: 289 +-- Name: Insight_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."Insight_id_seq"', 1, false); + + +-- +-- TOC entry 4539 (class 0 OID 0) +-- Dependencies: 237 +-- Name: IntegrationProvider_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."IntegrationProvider_id_seq"', 1, false); + + +-- +-- TOC entry 4540 (class 0 OID 0) +-- Dependencies: 249 +-- Name: IntegrationSearchQuery_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."IntegrationSearchQuery_id_seq"', 1, false); + + +-- +-- TOC entry 4541 (class 0 OID 0) +-- Dependencies: 255 +-- Name: JiraDimensionFieldMap_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."JiraDimensionFieldMap_id_seq"', 1, false); + + +-- +-- TOC entry 4542 (class 0 OID 0) +-- Dependencies: 247 +-- Name: JiraServerDimensionFieldMap_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."JiraServerDimensionFieldMap_id_seq"', 1, false); + + +-- +-- TOC entry 4543 (class 0 OID 0) +-- Dependencies: 253 +-- Name: MeetingSeries_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."MeetingSeries_id_seq"', 1, false); + + +-- +-- TOC entry 4544 (class 0 OID 0) +-- Dependencies: 306 +-- Name: NewFeature_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."NewFeature_id_seq"', 1, false); + + +-- +-- TOC entry 4545 (class 0 OID 0) +-- Dependencies: 251 +-- Name: OrganizationApprovedDomain_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."OrganizationApprovedDomain_id_seq"', 1, false); + + +-- +-- TOC entry 4546 (class 0 OID 0) +-- Dependencies: 218 +-- Name: OrganizationUserAudit_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."OrganizationUserAudit_id_seq"', 1, false); + + +-- +-- TOC entry 4547 (class 0 OID 0) +-- Dependencies: 297 +-- Name: PasswordResetRequest_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."PasswordResetRequest_id_seq"', 1, false); + + +-- +-- TOC entry 4548 (class 0 OID 0) +-- Dependencies: 231 +-- Name: PollOption_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."PollOption_id_seq"', 1, false); + + +-- +-- TOC entry 4549 (class 0 OID 0) +-- Dependencies: 229 +-- Name: Poll_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."Poll_id_seq"', 1, false); + + +-- +-- TOC entry 4550 (class 0 OID 0) +-- Dependencies: 299 +-- Name: PushInvitation_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."PushInvitation_id_seq"', 1, false); + + +-- +-- TOC entry 4551 (class 0 OID 0) +-- Dependencies: 272 +-- Name: ScheduledJob_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."ScheduledJob_id_seq"', 1, false); + + +-- +-- TOC entry 4552 (class 0 OID 0) +-- Dependencies: 235 +-- Name: StripeQuantityMismatchLogging_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."StripeQuantityMismatchLogging_id_seq"', 1, false); + + +-- +-- TOC entry 4553 (class 0 OID 0) +-- Dependencies: 227 +-- Name: TaskEstimate_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."TaskEstimate_id_seq"', 1, false); + + +-- +-- TOC entry 4554 (class 0 OID 0) +-- Dependencies: 241 +-- Name: TeamPromptResponse_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."TeamPromptResponse_id_seq"', 1, false); + + +-- +-- TOC entry 4555 (class 0 OID 0) +-- Dependencies: 283 +-- Name: TemplateScaleValue_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - +-- + +SELECT pg_catalog.setval('public."TemplateScaleValue_id_seq"', 38, true); + + +-- +-- TOC entry 4034 (class 2606 OID 2495228) +-- Name: AgendaItem AgendaItem_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AgendaItem" + ADD CONSTRAINT "AgendaItem_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3878 (class 2606 OID 2493866) +-- Name: AtlassianAuth AtlassianAuth_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AtlassianAuth" + ADD CONSTRAINT "AtlassianAuth_pkey" PRIMARY KEY ("userId", "teamId"); + + +-- +-- TOC entry 3908 (class 2606 OID 2494084) +-- Name: AzureDevOpsDimensionFieldMap AzureDevOpsDimensionFieldMap_id_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AzureDevOpsDimensionFieldMap" + ADD CONSTRAINT "AzureDevOpsDimensionFieldMap_id_key" UNIQUE (id); + + +-- +-- TOC entry 3910 (class 2606 OID 2494147) +-- Name: AzureDevOpsDimensionFieldMap AzureDevOpsDimensionFieldMap_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AzureDevOpsDimensionFieldMap" + ADD CONSTRAINT "AzureDevOpsDimensionFieldMap_pkey" PRIMARY KEY ("teamId", "dimensionName", "instanceId", "projectKey", "workItemType"); + + +-- +-- TOC entry 4051 (class 2606 OID 2495311) +-- Name: Comment Comment_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Comment" + ADD CONSTRAINT "Comment_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3873 (class 2606 OID 2493852) +-- Name: Discussion Discussion_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Discussion" + ADD CONSTRAINT "Discussion_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3933 (class 2606 OID 2494269) +-- Name: DomainJoinRequest DomainJoinRequest_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."DomainJoinRequest" + ADD CONSTRAINT "DomainJoinRequest_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4014 (class 2606 OID 2495108) +-- Name: EmailVerification EmailVerification_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmailVerification" + ADD CONSTRAINT "EmailVerification_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3959 (class 2606 OID 2494436) +-- Name: EmbeddingsJobQueue EmbeddingsJobQueue_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmbeddingsJobQueue" + ADD CONSTRAINT "EmbeddingsJobQueue_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3952 (class 2606 OID 2494420) +-- Name: EmbeddingsMetadata EmbeddingsMetadata_objectType_refId_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmbeddingsMetadata" + ADD CONSTRAINT "EmbeddingsMetadata_objectType_refId_key" UNIQUE ("objectType", "refId"); + + +-- +-- TOC entry 3954 (class 2606 OID 2494418) +-- Name: EmbeddingsMetadata EmbeddingsMetadata_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmbeddingsMetadata" + ADD CONSTRAINT "EmbeddingsMetadata_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3963 (class 2606 OID 2494451) +-- Name: FailedAuthRequest FailedAuthRequest_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FailedAuthRequest" + ADD CONSTRAINT "FailedAuthRequest_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4078 (class 2606 OID 2495460) +-- Name: FeatureFlag FeatureFlag_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlag" + ADD CONSTRAINT "FeatureFlag_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3950 (class 2606 OID 2494356) +-- Name: FreemailDomain FreemailDomain_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FreemailDomain" + ADD CONSTRAINT "FreemailDomain_pkey" PRIMARY KEY (domain); + + +-- +-- TOC entry 3864 (class 2606 OID 2493671) +-- Name: GitHubAuth GitHubAuth_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitHubAuth" + ADD CONSTRAINT "GitHubAuth_pkey" PRIMARY KEY ("userId", "teamId"); + + +-- +-- TOC entry 3888 (class 2606 OID 2493934) +-- Name: GitHubDimensionFieldMap GitHubDimensionFieldMap_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitHubDimensionFieldMap" + ADD CONSTRAINT "GitHubDimensionFieldMap_pkey" PRIMARY KEY ("teamId", "dimensionName", "nameWithOwner"); + + +-- +-- TOC entry 3904 (class 2606 OID 2494071) +-- Name: GitLabDimensionFieldMap GitLabDimensionFieldMap_id_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitLabDimensionFieldMap" + ADD CONSTRAINT "GitLabDimensionFieldMap_id_key" UNIQUE (id); + + +-- +-- TOC entry 3906 (class 2606 OID 2494069) +-- Name: GitLabDimensionFieldMap GitLabDimensionFieldMap_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitLabDimensionFieldMap" + ADD CONSTRAINT "GitLabDimensionFieldMap_pkey" PRIMARY KEY ("teamId", "dimensionName", "projectId", "providerId"); + + +-- +-- TOC entry 4024 (class 2606 OID 2495161) +-- Name: Insight Insight_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Insight" + ADD CONSTRAINT "Insight_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3890 (class 2606 OID 2493999) +-- Name: IntegrationProvider IntegrationProvider_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationProvider" + ADD CONSTRAINT "IntegrationProvider_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3916 (class 2606 OID 2494117) +-- Name: IntegrationSearchQuery IntegrationSearchQuery_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationSearchQuery" + ADD CONSTRAINT "IntegrationSearchQuery_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3926 (class 2606 OID 2494179) +-- Name: JiraDimensionFieldMap JiraDimensionFieldMap_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraDimensionFieldMap" + ADD CONSTRAINT "JiraDimensionFieldMap_pkey" PRIMARY KEY ("teamId", "cloudId", "projectKey", "issueType", "dimensionName"); + + +-- +-- TOC entry 3912 (class 2606 OID 2494097) +-- Name: JiraServerDimensionFieldMap JiraServerDimensionFieldMap_id_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraServerDimensionFieldMap" + ADD CONSTRAINT "JiraServerDimensionFieldMap_id_key" UNIQUE (id); + + +-- +-- TOC entry 3914 (class 2606 OID 2494095) +-- Name: JiraServerDimensionFieldMap JiraServerDimensionFieldMap_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraServerDimensionFieldMap" + ADD CONSTRAINT "JiraServerDimensionFieldMap_pkey" PRIMARY KEY ("providerId", "teamId", "projectId", "issueType", "dimensionName"); + + +-- +-- TOC entry 4093 (class 2606 OID 2495525) +-- Name: MassInvitation MassInvitation_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MassInvitation" + ADD CONSTRAINT "MassInvitation_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4088 (class 2606 OID 2495501) +-- Name: MeetingMember MeetingMember_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingMember" + ADD CONSTRAINT "MeetingMember_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3924 (class 2606 OID 2494157) +-- Name: MeetingSeries MeetingSeries_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSeries" + ADD CONSTRAINT "MeetingSeries_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4029 (class 2606 OID 2495203) +-- Name: MeetingSettings MeetingSettings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSettings" + ADD CONSTRAINT "MeetingSettings_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4031 (class 2606 OID 2495205) +-- Name: MeetingSettings MeetingSettings_teamId_meetingType_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSettings" + ADD CONSTRAINT "MeetingSettings_teamId_meetingType_key" UNIQUE ("teamId", "meetingType"); + + +-- +-- TOC entry 3928 (class 2606 OID 2494215) +-- Name: MeetingTemplate MeetingTemplate_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingTemplate" + ADD CONSTRAINT "MeetingTemplate_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4097 (class 2606 OID 2495545) +-- Name: NewFeature NewFeature_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewFeature" + ADD CONSTRAINT "NewFeature_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4070 (class 2606 OID 2495409) +-- Name: NewMeeting NewMeeting_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewMeeting" + ADD CONSTRAINT "NewMeeting_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4113 (class 2606 OID 2495711) +-- Name: Notification Notification_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "Notification_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3920 (class 2606 OID 2494138) +-- Name: OrganizationApprovedDomain OrganizationApprovedDomain_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationApprovedDomain" + ADD CONSTRAINT "OrganizationApprovedDomain_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3857 (class 2606 OID 2493646) +-- Name: OrganizationUserAudit OrganizationUserAudit_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUserAudit" + ADD CONSTRAINT "OrganizationUserAudit_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3986 (class 2606 OID 2494977) +-- Name: OrganizationUser OrganizationUser_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUser" + ADD CONSTRAINT "OrganizationUser_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3982 (class 2606 OID 2494962) +-- Name: Organization Organization_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Organization" + ADD CONSTRAINT "Organization_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4061 (class 2606 OID 2495376) +-- Name: PasswordResetRequest PasswordResetRequest_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."PasswordResetRequest" + ADD CONSTRAINT "PasswordResetRequest_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3885 (class 2606 OID 2493920) +-- Name: PollOption PollOption_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."PollOption" + ADD CONSTRAINT "PollOption_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3882 (class 2606 OID 2493893) +-- Name: Poll Poll_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Poll" + ADD CONSTRAINT "Poll_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4066 (class 2606 OID 2495386) +-- Name: PushInvitation PushInvitation_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."PushInvitation" + ADD CONSTRAINT "PushInvitation_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3997 (class 2606 OID 2495029) +-- Name: QueryMap QueryMap_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."QueryMap" + ADD CONSTRAINT "QueryMap_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4056 (class 2606 OID 2495347) +-- Name: ReflectPrompt ReflectPrompt_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ReflectPrompt" + ADD CONSTRAINT "ReflectPrompt_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3935 (class 2606 OID 2494288) +-- Name: RetroReflectionGroup RetroReflectionGroup_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflectionGroup" + ADD CONSTRAINT "RetroReflectionGroup_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3972 (class 2606 OID 2494889) +-- Name: RetroReflection RetroReflection_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflection" + ADD CONSTRAINT "RetroReflection_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3947 (class 2606 OID 2494344) +-- Name: SAMLDomain SAMLDomain_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SAMLDomain" + ADD CONSTRAINT "SAMLDomain_pkey" PRIMARY KEY (domain); + + +-- +-- TOC entry 3942 (class 2606 OID 2494331) +-- Name: SAML SAML_orgId_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SAML" + ADD CONSTRAINT "SAML_orgId_key" UNIQUE ("orgId"); + + +-- +-- TOC entry 3944 (class 2606 OID 2494329) +-- Name: SAML SAML_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SAML" + ADD CONSTRAINT "SAML_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3967 (class 2606 OID 2494468) +-- Name: ScheduledJob ScheduledJob_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ScheduledJob" + ADD CONSTRAINT "ScheduledJob_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4039 (class 2606 OID 2495252) +-- Name: SlackAuth SlackAuth_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackAuth" + ADD CONSTRAINT "SlackAuth_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4041 (class 2606 OID 2495254) +-- Name: SlackAuth SlackAuth_teamId_userId_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackAuth" + ADD CONSTRAINT "SlackAuth_teamId_userId_key" UNIQUE ("teamId", "userId"); + + +-- +-- TOC entry 4045 (class 2606 OID 2495285) +-- Name: SlackNotification SlackNotification_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackNotification" + ADD CONSTRAINT "SlackNotification_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4047 (class 2606 OID 2495287) +-- Name: SlackNotification SlackNotification_teamId_userId_event_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackNotification" + ADD CONSTRAINT "SlackNotification_teamId_userId_event_key" UNIQUE ("teamId", "userId", event); + + +-- +-- TOC entry 4018 (class 2606 OID 2495129) +-- Name: SuggestedAction SuggestedAction_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SuggestedAction" + ADD CONSTRAINT "SuggestedAction_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4020 (class 2606 OID 2495131) +-- Name: SuggestedAction SuggestedAction_userId_type_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SuggestedAction" + ADD CONSTRAINT "SuggestedAction_userId_type_key" UNIQUE ("userId", type); + + +-- +-- TOC entry 4104 (class 2606 OID 2495618) +-- Name: Task Task_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "Task_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4099 (class 2606 OID 2495567) +-- Name: TeamInvitation TeamInvitation_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamInvitation" + ADD CONSTRAINT "TeamInvitation_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3939 (class 2606 OID 2494308) +-- Name: TeamMeetingTemplate TeamMeetingTemplate_teamId_templateId_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMeetingTemplate" + ADD CONSTRAINT "TeamMeetingTemplate_teamId_templateId_key" UNIQUE ("teamId", "templateId"); + + +-- +-- TOC entry 3895 (class 2606 OID 2494017) +-- Name: TeamMemberIntegrationAuth TeamMemberIntegrationAuth_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMemberIntegrationAuth" + ADD CONSTRAINT "TeamMemberIntegrationAuth_pkey" PRIMARY KEY ("userId", "teamId", service); + + +-- +-- TOC entry 3993 (class 2606 OID 2495008) +-- Name: TeamMember TeamMember_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMember" + ADD CONSTRAINT "TeamMember_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3899 (class 2606 OID 2494073) +-- Name: TeamPromptResponse TeamPromptResponse_meetingIdUserId_unique; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamPromptResponse" + ADD CONSTRAINT "TeamPromptResponse_meetingIdUserId_unique" UNIQUE ("meetingId", "userId"); + + +-- +-- TOC entry 3901 (class 2606 OID 2494055) +-- Name: TeamPromptResponse TeamPromptResponse_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamPromptResponse" + ADD CONSTRAINT "TeamPromptResponse_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3870 (class 2606 OID 2493828) +-- Name: Team Team_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Team" + ADD CONSTRAINT "Team_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4007 (class 2606 OID 2495075) +-- Name: TemplateDimension TemplateDimension_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateDimension" + ADD CONSTRAINT "TemplateDimension_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4009 (class 2606 OID 2495077) +-- Name: TemplateDimension TemplateDimension_teamId_name_removedAt_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateDimension" + ADD CONSTRAINT "TemplateDimension_teamId_name_removedAt_key" UNIQUE ("teamId", name, "removedAt"); + + +-- +-- TOC entry 3862 (class 2606 OID 2493663) +-- Name: TemplateRef TemplateRef_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateRef" + ADD CONSTRAINT "TemplateRef_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3860 (class 2606 OID 2493655) +-- Name: TemplateScaleRef TemplateScaleRef_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScaleRef" + ADD CONSTRAINT "TemplateScaleRef_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4002 (class 2606 OID 2495050) +-- Name: TemplateScaleValue TemplateScaleValue_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScaleValue" + ADD CONSTRAINT "TemplateScaleValue_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4004 (class 2606 OID 2495052) +-- Name: TemplateScaleValue TemplateScaleValue_templateScaleId_label_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScaleValue" + ADD CONSTRAINT "TemplateScaleValue_templateScaleId_label_key" UNIQUE ("templateScaleId", label); + + +-- +-- TOC entry 3999 (class 2606 OID 2495037) +-- Name: TemplateScale TemplateScale_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScale" + ADD CONSTRAINT "TemplateScale_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3978 (class 2606 OID 2494933) +-- Name: TimelineEvent TimelineEvent_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TimelineEvent" + ADD CONSTRAINT "TimelineEvent_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 3866 (class 2606 OID 2493803) +-- Name: User User_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."User" + ADD CONSTRAINT "User_pkey" PRIMARY KEY (id); + + +-- +-- TOC entry 4080 (class 2606 OID 2495462) +-- Name: FeatureFlag unique_featureName_scope; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlag" + ADD CONSTRAINT "unique_featureName_scope" UNIQUE ("featureName", scope); + + +-- +-- TOC entry 4082 (class 2606 OID 2495475) +-- Name: FeatureFlagOwner unique_feature_flag_owner_org; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT unique_feature_flag_owner_org UNIQUE ("orgId", "featureFlagId"); + + +-- +-- TOC entry 4084 (class 2606 OID 2495473) +-- Name: FeatureFlagOwner unique_feature_flag_owner_team; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT unique_feature_flag_owner_team UNIQUE ("teamId", "featureFlagId"); + + +-- +-- TOC entry 4086 (class 2606 OID 2495471) +-- Name: FeatureFlagOwner unique_feature_flag_owner_user; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT unique_feature_flag_owner_user UNIQUE ("userId", "featureFlagId"); + + +-- +-- TOC entry 3991 (class 2606 OID 2495338) +-- Name: OrganizationUser unique_org_user; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUser" + ADD CONSTRAINT unique_org_user UNIQUE ("orgId", "userId"); + + +-- +-- TOC entry 3893 (class 2606 OID 2495150) +-- Name: IntegrationProvider unique_per_team_and_org; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationProvider" + ADD CONSTRAINT unique_per_team_and_org UNIQUE NULLS NOT DISTINCT ("orgId", "teamId", service, "authStrategy"); + + +-- +-- TOC entry 3931 (class 1259 OID 2494275) +-- Name: DomainJoinRequest_createdBy_domain_unique; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "DomainJoinRequest_createdBy_domain_unique" ON public."DomainJoinRequest" USING btree ("createdBy", domain); + + +-- +-- TOC entry 4035 (class 1259 OID 2495240) +-- Name: idx_AgendaItem_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_AgendaItem_meetingId" ON public."AgendaItem" USING btree ("meetingId"); + + +-- +-- TOC entry 4036 (class 1259 OID 2495239) +-- Name: idx_AgendaItem_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_AgendaItem_teamId" ON public."AgendaItem" USING btree ("teamId"); + + +-- +-- TOC entry 4037 (class 1259 OID 2495241) +-- Name: idx_AgendaItem_teamMemberId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_AgendaItem_teamMemberId" ON public."AgendaItem" USING btree ("teamMemberId"); + + +-- +-- TOC entry 4052 (class 1259 OID 2495323) +-- Name: idx_Comment_createdBy; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Comment_createdBy" ON public."Comment" USING btree ("createdBy"); + + +-- +-- TOC entry 4053 (class 1259 OID 2495324) +-- Name: idx_Comment_discussionId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Comment_discussionId" ON public."Comment" USING btree ("discussionId"); + + +-- +-- TOC entry 4054 (class 1259 OID 2495322) +-- Name: idx_Comment_threadParentId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Comment_threadParentId" ON public."Comment" USING btree ("threadParentId"); + + +-- +-- TOC entry 3874 (class 1259 OID 2494843) +-- Name: idx_Discussion_createdAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Discussion_createdAt" ON public."Discussion" USING btree ("createdAt"); + + +-- +-- TOC entry 4015 (class 1259 OID 2495109) +-- Name: idx_EmailVerification_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmailVerification_email" ON public."EmailVerification" USING btree (email); + + +-- +-- TOC entry 4016 (class 1259 OID 2495110) +-- Name: idx_EmailVerification_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmailVerification_token" ON public."EmailVerification" USING btree (token); + + +-- +-- TOC entry 3960 (class 1259 OID 2494849) +-- Name: idx_EmbeddingsJobQueue_priority; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmbeddingsJobQueue_priority" ON public."EmbeddingsJobQueue" USING btree (priority); + + +-- +-- TOC entry 3961 (class 1259 OID 2494442) +-- Name: idx_EmbeddingsJobQueue_state; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmbeddingsJobQueue_state" ON public."EmbeddingsJobQueue" USING btree (state); + + +-- +-- TOC entry 3955 (class 1259 OID 2494422) +-- Name: idx_EmbeddingsMetadata_objectType; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmbeddingsMetadata_objectType" ON public."EmbeddingsMetadata" USING btree ("objectType"); + + +-- +-- TOC entry 3956 (class 1259 OID 2494423) +-- Name: idx_EmbeddingsMetadata_refUpdatedAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmbeddingsMetadata_refUpdatedAt" ON public."EmbeddingsMetadata" USING btree ("refUpdatedAt"); + + +-- +-- TOC entry 3957 (class 1259 OID 2494425) +-- Name: idx_EmbeddingsMetadata_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_EmbeddingsMetadata_teamId" ON public."EmbeddingsMetadata" USING btree ("teamId"); + + +-- +-- TOC entry 3964 (class 1259 OID 2494452) +-- Name: idx_FailedAuthRequest_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_FailedAuthRequest_email" ON public."FailedAuthRequest" USING btree (email); + + +-- +-- TOC entry 3965 (class 1259 OID 2494453) +-- Name: idx_FailedAuthRequest_ip; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_FailedAuthRequest_ip" ON public."FailedAuthRequest" USING btree (ip); + + +-- +-- TOC entry 3891 (class 1259 OID 2494007) +-- Name: idx_IntegrationProvider_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_IntegrationProvider_teamId" ON public."IntegrationProvider" USING btree ("teamId"); + + +-- +-- TOC entry 4094 (class 1259 OID 2495536) +-- Name: idx_MassInvitation_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MassInvitation_meetingId" ON public."MassInvitation" USING btree ("meetingId") WHERE ("meetingId" IS NOT NULL); + + +-- +-- TOC entry 4095 (class 1259 OID 2495537) +-- Name: idx_MassInvitation_teamMemberId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MassInvitation_teamMemberId" ON public."MassInvitation" USING btree ("teamMemberId"); + + +-- +-- TOC entry 4089 (class 1259 OID 2495517) +-- Name: idx_MeetingMember_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MeetingMember_meetingId" ON public."MeetingMember" USING btree ("meetingId"); + + +-- +-- TOC entry 4090 (class 1259 OID 2495518) +-- Name: idx_MeetingMember_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MeetingMember_teamId" ON public."MeetingMember" USING btree ("teamId"); + + +-- +-- TOC entry 4091 (class 1259 OID 2495519) +-- Name: idx_MeetingMember_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MeetingMember_userId" ON public."MeetingMember" USING btree ("userId"); + + +-- +-- TOC entry 4032 (class 1259 OID 2495216) +-- Name: idx_MeetingSettings_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MeetingSettings_teamId" ON public."MeetingSettings" USING btree ("teamId"); + + +-- +-- TOC entry 3929 (class 1259 OID 2494222) +-- Name: idx_MeetingTemplate_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MeetingTemplate_orgId" ON public."MeetingTemplate" USING btree ("orgId"); + + +-- +-- TOC entry 3930 (class 1259 OID 2494221) +-- Name: idx_MeetingTemplate_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_MeetingTemplate_teamId" ON public."MeetingTemplate" USING btree ("teamId"); + + +-- +-- TOC entry 4071 (class 1259 OID 2495435) +-- Name: idx_NewMeeting_createdAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_NewMeeting_createdAt" ON public."NewMeeting" USING btree ("createdAt"); + + +-- +-- TOC entry 4072 (class 1259 OID 2495436) +-- Name: idx_NewMeeting_facilitatorUserId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_NewMeeting_facilitatorUserId" ON public."NewMeeting" USING btree ("facilitatorUserId"); + + +-- +-- TOC entry 4073 (class 1259 OID 2495438) +-- Name: idx_NewMeeting_meetingSeriesId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_NewMeeting_meetingSeriesId" ON public."NewMeeting" USING btree ("meetingSeriesId") WHERE ("meetingSeriesId" IS NOT NULL); + + +-- +-- TOC entry 4074 (class 1259 OID 2495437) +-- Name: idx_NewMeeting_scheduledEndTime; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_NewMeeting_scheduledEndTime" ON public."NewMeeting" USING btree ("scheduledEndTime") WHERE (("scheduledEndTime" IS NOT NULL) AND ("endedAt" IS NULL)); + + +-- +-- TOC entry 4075 (class 1259 OID 2495439) +-- Name: idx_NewMeeting_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_NewMeeting_teamId" ON public."NewMeeting" USING btree ("teamId"); + + +-- +-- TOC entry 4076 (class 1259 OID 2495440) +-- Name: idx_NewMeeting_templateId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_NewMeeting_templateId" ON public."NewMeeting" USING btree ("templateId") WHERE ("templateId" IS NOT NULL); + + +-- +-- TOC entry 4114 (class 1259 OID 2495798) +-- Name: idx_Notification_createdAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Notification_createdAt" ON public."Notification" USING btree ("createdAt"); + + +-- +-- TOC entry 4115 (class 1259 OID 2495800) +-- Name: idx_Notification_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Notification_orgId" ON public."Notification" USING btree ("orgId") WHERE ("orgId" IS NOT NULL); + + +-- +-- TOC entry 4116 (class 1259 OID 2495799) +-- Name: idx_Notification_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Notification_teamId" ON public."Notification" USING btree ("teamId") WHERE ("teamId" IS NOT NULL); + + +-- +-- TOC entry 4117 (class 1259 OID 2495797) +-- Name: idx_Notification_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Notification_userId" ON public."Notification" USING btree ("userId"); + + +-- +-- TOC entry 3921 (class 1259 OID 2494145) +-- Name: idx_OrganizationApprovedDomain_domain; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_OrganizationApprovedDomain_domain" ON public."OrganizationApprovedDomain" USING btree (domain); + + +-- +-- TOC entry 3922 (class 1259 OID 2494144) +-- Name: idx_OrganizationApprovedDomain_orgId_domain; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "idx_OrganizationApprovedDomain_orgId_domain" ON public."OrganizationApprovedDomain" USING btree ("orgId", domain, (("removedAt" IS NULL))) WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 3858 (class 1259 OID 2493647) +-- Name: idx_OrganizationUserAudit_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_OrganizationUserAudit_orgId" ON public."OrganizationUserAudit" USING btree ("orgId"); + + +-- +-- TOC entry 3987 (class 1259 OID 2494989) +-- Name: idx_OrganizationUser_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_OrganizationUser_orgId" ON public."OrganizationUser" USING btree ("orgId") WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 3988 (class 1259 OID 2494988) +-- Name: idx_OrganizationUser_tier; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_OrganizationUser_tier" ON public."OrganizationUser" USING btree (tier) WHERE (("removedAt" IS NULL) AND (inactive = false)); + + +-- +-- TOC entry 3989 (class 1259 OID 2494990) +-- Name: idx_OrganizationUser_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_OrganizationUser_userId" ON public."OrganizationUser" USING btree ("userId") WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 3983 (class 1259 OID 2494963) +-- Name: idx_Organization_activeDomain; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Organization_activeDomain" ON public."Organization" USING btree ("activeDomain"); + + +-- +-- TOC entry 3984 (class 1259 OID 2494964) +-- Name: idx_Organization_tier; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Organization_tier" ON public."Organization" USING btree (tier); + + +-- +-- TOC entry 4062 (class 1259 OID 2495378) +-- Name: idx_PasswordResetRequest_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_PasswordResetRequest_email" ON public."PasswordResetRequest" USING btree (email); + + +-- +-- TOC entry 4063 (class 1259 OID 2495377) +-- Name: idx_PasswordResetRequest_ip; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_PasswordResetRequest_ip" ON public."PasswordResetRequest" USING btree (ip); + + +-- +-- TOC entry 4064 (class 1259 OID 2495379) +-- Name: idx_PasswordResetRequest_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_PasswordResetRequest_token" ON public."PasswordResetRequest" USING btree (token); + + +-- +-- TOC entry 3886 (class 1259 OID 2493926) +-- Name: idx_PollOption_pollId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_PollOption_pollId" ON public."PollOption" USING btree ("pollId"); + + +-- +-- TOC entry 3883 (class 1259 OID 2493909) +-- Name: idx_Poll_discussionId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Poll_discussionId" ON public."Poll" USING btree ("discussionId"); + + +-- +-- TOC entry 4067 (class 1259 OID 2495398) +-- Name: idx_PushInvitation_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_PushInvitation_teamId" ON public."PushInvitation" USING btree ("teamId"); + + +-- +-- TOC entry 4068 (class 1259 OID 2495397) +-- Name: idx_PushInvitation_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_PushInvitation_userId" ON public."PushInvitation" USING btree ("userId"); + + +-- +-- TOC entry 4057 (class 1259 OID 2495360) +-- Name: idx_ReflectPrompt_parentPromptId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_ReflectPrompt_parentPromptId" ON public."ReflectPrompt" USING btree ("templateId"); + + +-- +-- TOC entry 4058 (class 1259 OID 2495358) +-- Name: idx_ReflectPrompt_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_ReflectPrompt_teamId" ON public."ReflectPrompt" USING btree ("teamId"); + + +-- +-- TOC entry 4059 (class 1259 OID 2495359) +-- Name: idx_ReflectPrompt_templateId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_ReflectPrompt_templateId" ON public."ReflectPrompt" USING btree ("templateId"); + + +-- +-- TOC entry 3936 (class 1259 OID 2494289) +-- Name: idx_RetroReflectionGroup_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_RetroReflectionGroup_meetingId" ON public."RetroReflectionGroup" USING btree ("meetingId"); + + +-- +-- TOC entry 3937 (class 1259 OID 2494864) +-- Name: idx_RetroReflectionGroup_promptId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_RetroReflectionGroup_promptId" ON public."RetroReflectionGroup" USING btree ("promptId"); + + +-- +-- TOC entry 3973 (class 1259 OID 2494902) +-- Name: idx_RetroReflection_creatorId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_RetroReflection_creatorId" ON public."RetroReflection" USING btree ("creatorId"); + + +-- +-- TOC entry 3974 (class 1259 OID 2494900) +-- Name: idx_RetroReflection_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_RetroReflection_meetingId" ON public."RetroReflection" USING btree ("meetingId"); + + +-- +-- TOC entry 3975 (class 1259 OID 2494901) +-- Name: idx_RetroReflection_promptId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_RetroReflection_promptId" ON public."RetroReflection" USING btree ("promptId"); + + +-- +-- TOC entry 3976 (class 1259 OID 2494903) +-- Name: idx_RetroReflection_reflectionGroupId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_RetroReflection_reflectionGroupId" ON public."RetroReflection" USING btree ("reflectionGroupId"); + + +-- +-- TOC entry 3948 (class 1259 OID 2494350) +-- Name: idx_SAMLDomain_samlId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SAMLDomain_samlId" ON public."SAMLDomain" USING btree ("samlId"); + + +-- +-- TOC entry 3945 (class 1259 OID 2494337) +-- Name: idx_SAML_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SAML_orgId" ON public."SAML" USING btree ("orgId"); + + +-- +-- TOC entry 3968 (class 1259 OID 2494469) +-- Name: idx_ScheduledJob_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_ScheduledJob_orgId" ON public."ScheduledJob" USING btree ("orgId"); + + +-- +-- TOC entry 3969 (class 1259 OID 2494470) +-- Name: idx_ScheduledJob_runAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_ScheduledJob_runAt" ON public."ScheduledJob" USING btree ("runAt"); + + +-- +-- TOC entry 3970 (class 1259 OID 2494471) +-- Name: idx_ScheduledJob_type; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_ScheduledJob_type" ON public."ScheduledJob" USING btree (type); + + +-- +-- TOC entry 4042 (class 1259 OID 2495265) +-- Name: idx_SlackAuth_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SlackAuth_teamId" ON public."SlackAuth" USING btree ("teamId"); + + +-- +-- TOC entry 4043 (class 1259 OID 2495266) +-- Name: idx_SlackAuth_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SlackAuth_userId" ON public."SlackAuth" USING btree ("userId"); + + +-- +-- TOC entry 4048 (class 1259 OID 2495298) +-- Name: idx_SlackNotification_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SlackNotification_teamId" ON public."SlackNotification" USING btree ("teamId"); + + +-- +-- TOC entry 4049 (class 1259 OID 2495299) +-- Name: idx_SlackNotification_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SlackNotification_userId" ON public."SlackNotification" USING btree ("userId"); + + +-- +-- TOC entry 4021 (class 1259 OID 2495142) +-- Name: idx_SuggestedAction_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SuggestedAction_teamId" ON public."SuggestedAction" USING btree ("teamId"); + + +-- +-- TOC entry 4022 (class 1259 OID 2495143) +-- Name: idx_SuggestedAction_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_SuggestedAction_userId" ON public."SuggestedAction" USING btree ("userId"); + + +-- +-- TOC entry 3879 (class 1259 OID 2493883) +-- Name: idx_TaskEstimate_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TaskEstimate_meetingId" ON public."TaskEstimate" USING btree ("meetingId"); + + +-- +-- TOC entry 3880 (class 1259 OID 2493882) +-- Name: idx_TaskEstimate_taskId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TaskEstimate_taskId" ON public."TaskEstimate" USING btree ("taskId"); + + +-- +-- TOC entry 4105 (class 1259 OID 2495649) +-- Name: idx_Task_createdBy; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_createdBy" ON public."Task" USING btree ("createdBy"); + + +-- +-- TOC entry 4106 (class 1259 OID 2495650) +-- Name: idx_Task_discussionId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_discussionId" ON public."Task" USING btree ("discussionId") WHERE ("discussionId" IS NOT NULL); + + +-- +-- TOC entry 4107 (class 1259 OID 2495651) +-- Name: idx_Task_integrationHash; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_integrationHash" ON public."Task" USING btree ("integrationHash") WHERE ("integrationHash" IS NOT NULL); + + +-- +-- TOC entry 4108 (class 1259 OID 2495652) +-- Name: idx_Task_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_meetingId" ON public."Task" USING btree ("meetingId") WHERE ("meetingId" IS NOT NULL); + + +-- +-- TOC entry 4109 (class 1259 OID 2495653) +-- Name: idx_Task_teamId_updatedAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_teamId_updatedAt" ON public."Task" USING btree ("teamId", "updatedAt" DESC); + + +-- +-- TOC entry 4110 (class 1259 OID 2495654) +-- Name: idx_Task_threadParentId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_threadParentId" ON public."Task" USING btree ("threadParentId") WHERE ("threadParentId" IS NOT NULL); + + +-- +-- TOC entry 4111 (class 1259 OID 2495655) +-- Name: idx_Task_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Task_userId" ON public."Task" USING btree ("userId") WHERE ("userId" IS NOT NULL); + + +-- +-- TOC entry 4100 (class 1259 OID 2495588) +-- Name: idx_TeamInvitation_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamInvitation_email" ON public."TeamInvitation" USING btree (email); + + +-- +-- TOC entry 4101 (class 1259 OID 2495589) +-- Name: idx_TeamInvitation_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamInvitation_teamId" ON public."TeamInvitation" USING btree ("teamId"); + + +-- +-- TOC entry 4102 (class 1259 OID 2495590) +-- Name: idx_TeamInvitation_token; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamInvitation_token" ON public."TeamInvitation" USING btree (token); + + +-- +-- TOC entry 3940 (class 1259 OID 2494319) +-- Name: idx_TeamMeetingTemplate_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamMeetingTemplate_teamId" ON public."TeamMeetingTemplate" USING btree ("teamId"); + + +-- +-- TOC entry 3896 (class 1259 OID 2494034) +-- Name: idx_TeamMemberIntegrationAuths_providerId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamMemberIntegrationAuths_providerId" ON public."TeamMemberIntegrationAuth" USING btree ("providerId"); + + +-- +-- TOC entry 3897 (class 1259 OID 2494033) +-- Name: idx_TeamMemberIntegrationAuths_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamMemberIntegrationAuths_teamId" ON public."TeamMemberIntegrationAuth" USING btree ("teamId"); + + +-- +-- TOC entry 3994 (class 1259 OID 2495019) +-- Name: idx_TeamMember_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamMember_teamId" ON public."TeamMember" USING btree ("teamId") WHERE ("isNotRemoved" = true); + + +-- +-- TOC entry 3995 (class 1259 OID 2495020) +-- Name: idx_TeamMember_userId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamMember_userId" ON public."TeamMember" USING btree ("userId") WHERE ("isNotRemoved" = true); + + +-- +-- TOC entry 3902 (class 1259 OID 2494061) +-- Name: idx_TeamPromptResponse_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TeamPromptResponse_meetingId" ON public."TeamPromptResponse" USING btree ("meetingId"); + + +-- +-- TOC entry 3871 (class 1259 OID 2493829) +-- Name: idx_Team_orgId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Team_orgId" ON public."Team" USING btree ("orgId"); + + +-- +-- TOC entry 4010 (class 1259 OID 2495094) +-- Name: idx_TemplateDimension_scaleId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TemplateDimension_scaleId" ON public."TemplateDimension" USING btree ("scaleId") WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 4011 (class 1259 OID 2495093) +-- Name: idx_TemplateDimension_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TemplateDimension_teamId" ON public."TemplateDimension" USING btree ("teamId") WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 4012 (class 1259 OID 2495095) +-- Name: idx_TemplateDimension_templateId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TemplateDimension_templateId" ON public."TemplateDimension" USING btree ("templateId") WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 4005 (class 1259 OID 2495058) +-- Name: idx_TemplateScaleValue_templateScaleId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TemplateScaleValue_templateScaleId" ON public."TemplateScaleValue" USING btree ("templateScaleId"); + + +-- +-- TOC entry 4000 (class 1259 OID 2495043) +-- Name: idx_TemplateScale_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TemplateScale_teamId" ON public."TemplateScale" USING btree ("teamId") WHERE ("removedAt" IS NULL); + + +-- +-- TOC entry 3875 (class 1259 OID 2493854) +-- Name: idx_Thread_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Thread_meetingId" ON public."Discussion" USING btree ("meetingId"); + + +-- +-- TOC entry 3876 (class 1259 OID 2493853) +-- Name: idx_Thread_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_Thread_teamId" ON public."Discussion" USING btree ("teamId"); + + +-- +-- TOC entry 3979 (class 1259 OID 2494945) +-- Name: idx_TimelineEvent_meetingId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TimelineEvent_meetingId" ON public."TimelineEvent" USING btree ("meetingId"); + + +-- +-- TOC entry 3980 (class 1259 OID 2494944) +-- Name: idx_TimelineEvent_userId_createdAt; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_TimelineEvent_userId_createdAt" ON public."TimelineEvent" USING btree ("userId", "createdAt") WHERE ("isActive" = true); + + +-- +-- TOC entry 3867 (class 1259 OID 2493962) +-- Name: idx_User_domain; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_User_domain" ON public."User" USING btree (domain); + + +-- +-- TOC entry 3868 (class 1259 OID 2493927) +-- Name: idx_User_email; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX "idx_User_email" ON public."User" USING btree (email); + + +-- +-- TOC entry 4025 (class 1259 OID 2495164) +-- Name: idx_endDateTime; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_endDateTime" ON public."Insight" USING btree ("endDateTime"); + + +-- +-- TOC entry 4026 (class 1259 OID 2495163) +-- Name: idx_startDateTime; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_startDateTime" ON public."Insight" USING btree ("startDateTime"); + + +-- +-- TOC entry 4027 (class 1259 OID 2495162) +-- Name: idx_teamId; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX "idx_teamId" ON public."Insight" USING btree ("teamId"); + + +-- +-- TOC entry 3917 (class 1259 OID 2494128) +-- Name: integration_search_query_unique_not_null; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX integration_search_query_unique_not_null ON public."IntegrationSearchQuery" USING btree ("userId", "teamId", service, query, "providerId") WHERE ("providerId" IS NOT NULL); + + +-- +-- TOC entry 3918 (class 1259 OID 2494129) +-- Name: integration_search_query_unique_null; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX integration_search_query_unique_null ON public."IntegrationSearchQuery" USING btree ("userId", "teamId", service, query) WHERE ("providerId" IS NULL); + + +-- +-- TOC entry 4277 (class 2620 OID 2495443) +-- Name: NewMeeting check_meeting_overlap; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER check_meeting_overlap BEFORE INSERT ON public."NewMeeting" FOR EACH ROW EXECUTE FUNCTION public.prevent_meeting_overlap(); + + +-- +-- TOC entry 4274 (class 2620 OID 2495242) +-- Name: AgendaItem update_AgendaItem_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_AgendaItem_updatedAt" BEFORE UPDATE ON public."AgendaItem" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4250 (class 2620 OID 2494099) +-- Name: AtlassianAuth update_AtlassianAuth_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_AtlassianAuth_updatedAt" BEFORE UPDATE ON public."AtlassianAuth" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4261 (class 2620 OID 2494276) +-- Name: DomainJoinRequest update_DomainJoinRequest_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_DomainJoinRequest_updatedAt" BEFORE UPDATE ON public."DomainJoinRequest" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4265 (class 2620 OID 2494439) +-- Name: EmbeddingsJobQueue update_EmbeddingsJobQueue_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_EmbeddingsJobQueue_updatedAt" BEFORE UPDATE ON public."EmbeddingsJobQueue" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4264 (class 2620 OID 2494421) +-- Name: EmbeddingsMetadata update_EmbeddingsMetadata_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_EmbeddingsMetadata_updatedAt" BEFORE UPDATE ON public."EmbeddingsMetadata" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4247 (class 2620 OID 2494102) +-- Name: GitHubAuth update_GitHubAuth_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_GitHubAuth_updatedAt" BEFORE UPDATE ON public."GitHubAuth" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4253 (class 2620 OID 2494101) +-- Name: IntegrationProvider update_IntegrationProvider_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_IntegrationProvider_updatedAt" BEFORE UPDATE ON public."IntegrationProvider" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4256 (class 2620 OID 2494130) +-- Name: IntegrationSearchQuery update_IntegrationSearchQuery_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_IntegrationSearchQuery_updatedAt" BEFORE UPDATE ON public."IntegrationSearchQuery" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4258 (class 2620 OID 2494180) +-- Name: JiraDimensionFieldMap update_JiraDimensionFieldMap_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_JiraDimensionFieldMap_updatedAt" BEFORE UPDATE ON public."JiraDimensionFieldMap" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4279 (class 2620 OID 2495520) +-- Name: MeetingMember update_MeetingMember_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_MeetingMember_updatedAt" BEFORE UPDATE ON public."MeetingMember" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4257 (class 2620 OID 2494158) +-- Name: MeetingSeries update_MeetingSeries_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_MeetingSeries_updatedAt" BEFORE UPDATE ON public."MeetingSeries" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4259 (class 2620 OID 2494223) +-- Name: MeetingTemplate update_MeetingTemplate_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_MeetingTemplate_updatedAt" BEFORE UPDATE ON public."MeetingTemplate" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4276 (class 2620 OID 2495361) +-- Name: ReflectPrompt update_MeetingTemplate_updatedAt_from_ReflectPrompt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_MeetingTemplate_updatedAt_from_ReflectPrompt" AFTER INSERT OR DELETE OR UPDATE ON public."ReflectPrompt" FOR EACH ROW EXECUTE FUNCTION public."set_MeetingTemplate_updatedAt"(); + + +-- +-- TOC entry 4272 (class 2620 OID 2495100) +-- Name: TemplateDimension update_MeetingTemplate_updatedAt_from_TemplateDimension; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_MeetingTemplate_updatedAt_from_TemplateDimension" AFTER INSERT OR DELETE OR UPDATE ON public."TemplateDimension" FOR EACH ROW EXECUTE FUNCTION public."set_MeetingTemplate_updatedAt"(); + + +-- +-- TOC entry 4278 (class 2620 OID 2495441) +-- Name: NewMeeting update_NewMeeting_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_NewMeeting_updatedAt" BEFORE UPDATE ON public."NewMeeting" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4267 (class 2620 OID 2494965) +-- Name: Organization update_Organization_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_Organization_updatedAt" BEFORE UPDATE ON public."Organization" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4252 (class 2620 OID 2494104) +-- Name: PollOption update_PollOption_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_PollOption_updatedAt" BEFORE UPDATE ON public."PollOption" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4251 (class 2620 OID 2494103) +-- Name: Poll update_Poll_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_Poll_updatedAt" BEFORE UPDATE ON public."Poll" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4262 (class 2620 OID 2494291) +-- Name: RetroReflectionGroup update_RetroReflectionGroup_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_RetroReflectionGroup_updatedAt" BEFORE UPDATE ON public."RetroReflectionGroup" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4266 (class 2620 OID 2494904) +-- Name: RetroReflection update_RetroReflection_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_RetroReflection_updatedAt" BEFORE UPDATE ON public."RetroReflection" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4263 (class 2620 OID 2494338) +-- Name: SAML update_SAML_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_SAML_updatedAt" BEFORE UPDATE ON public."SAML" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4275 (class 2620 OID 2495267) +-- Name: SlackAuth update_SlackAuth_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_SlackAuth_updatedAt" BEFORE UPDATE ON public."SlackAuth" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4280 (class 2620 OID 2495656) +-- Name: Task update_Task_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_Task_updatedAt" BEFORE UPDATE ON public."Task" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4254 (class 2620 OID 2494100) +-- Name: TeamMemberIntegrationAuth update_TeamMemberIntegrationAuth_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TeamMemberIntegrationAuth_updatedAt" BEFORE UPDATE ON public."TeamMemberIntegrationAuth" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4268 (class 2620 OID 2495021) +-- Name: TeamMember update_TeamMember_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TeamMember_updatedAt" BEFORE UPDATE ON public."TeamMember" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4255 (class 2620 OID 2494105) +-- Name: TeamPromptResponse update_TeamPromptResponse_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TeamPromptResponse_updatedAt" BEFORE UPDATE ON public."TeamPromptResponse" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4249 (class 2620 OID 2494098) +-- Name: Team update_Team_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_Team_updatedAt" BEFORE UPDATE ON public."Team" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4273 (class 2620 OID 2495096) +-- Name: TemplateDimension update_TemplateDimension_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TemplateDimension_updatedAt" BEFORE UPDATE ON public."TemplateDimension" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4269 (class 2620 OID 2495098) +-- Name: TemplateScale update_TemplateDimension_updatedAt_from_TemplateScale; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TemplateDimension_updatedAt_from_TemplateScale" AFTER INSERT OR DELETE OR UPDATE ON public."TemplateScale" FOR EACH ROW EXECUTE FUNCTION public."set_TemplateDimension_updatedAt"(); + + +-- +-- TOC entry 4270 (class 2620 OID 2495044) +-- Name: TemplateScale update_TemplateScale_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TemplateScale_updatedAt" BEFORE UPDATE ON public."TemplateScale" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4271 (class 2620 OID 2495060) +-- Name: TemplateScaleValue update_TemplateScale_updatedAt_from_TemplateScaleValue; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_TemplateScale_updatedAt_from_TemplateScaleValue" AFTER INSERT OR DELETE OR UPDATE ON public."TemplateScaleValue" FOR EACH ROW EXECUTE FUNCTION public."set_TemplateScale_updatedAt"(); + + +-- +-- TOC entry 4248 (class 2620 OID 2493964) +-- Name: User update_User_updatedAt; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_User_updatedAt" BEFORE UPDATE ON public."User" FOR EACH ROW EXECUTE FUNCTION public."set_updatedAt"(); + + +-- +-- TOC entry 4260 (class 2620 OID 2494909) +-- Name: MeetingTemplate update_embedding_on_MeetingTemplate; Type: TRIGGER; Schema: public; Owner: - +-- + +CREATE TRIGGER "update_embedding_on_MeetingTemplate" AFTER INSERT OR UPDATE ON public."MeetingTemplate" FOR EACH ROW EXECUTE FUNCTION public."updateEmbedding"(); + + +-- +-- TOC entry 4160 (class 2606 OID 2494270) +-- Name: DomainJoinRequest DomainJoinRequest_createdBy_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."DomainJoinRequest" + ADD CONSTRAINT "DomainJoinRequest_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4211 (class 2606 OID 2495476) +-- Name: FeatureFlagOwner FeatureFlagOwner_featureFlagId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT "FeatureFlagOwner_featureFlagId_fkey" FOREIGN KEY ("featureFlagId") REFERENCES public."FeatureFlag"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4212 (class 2606 OID 2495491) +-- Name: FeatureFlagOwner FeatureFlagOwner_orgId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT "FeatureFlagOwner_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4213 (class 2606 OID 2495486) +-- Name: FeatureFlagOwner FeatureFlagOwner_teamId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT "FeatureFlagOwner_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4214 (class 2606 OID 2495481) +-- Name: FeatureFlagOwner FeatureFlagOwner_userId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."FeatureFlagOwner" + ADD CONSTRAINT "FeatureFlagOwner_userId_fkey" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4158 (class 2606 OID 2494250) +-- Name: MeetingTemplateUserFavorite MeetingTemplateUserFavorite_templateId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingTemplateUserFavorite" + ADD CONSTRAINT "MeetingTemplateUserFavorite_templateId_fkey" FOREIGN KEY ("templateId") REFERENCES public."MeetingTemplate"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4159 (class 2606 OID 2494245) +-- Name: MeetingTemplateUserFavorite MeetingTemplateUserFavorite_userId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingTemplateUserFavorite" + ADD CONSTRAINT "MeetingTemplateUserFavorite_userId_fkey" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4156 (class 2606 OID 2494216) +-- Name: MeetingTemplate MeetingTemplate_teamId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingTemplate" + ADD CONSTRAINT "MeetingTemplate_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4136 (class 2606 OID 2493921) +-- Name: PollOption PollOption_pollId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."PollOption" + ADD CONSTRAINT "PollOption_pollId_fkey" FOREIGN KEY ("pollId") REFERENCES public."Poll"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4132 (class 2606 OID 2493894) +-- Name: Poll Poll_createdById_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Poll" + ADD CONSTRAINT "Poll_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES public."User"(id); + + +-- +-- TOC entry 4133 (class 2606 OID 2493899) +-- Name: Poll Poll_discussionId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Poll" + ADD CONSTRAINT "Poll_discussionId_fkey" FOREIGN KEY ("discussionId") REFERENCES public."Discussion"(id); + + +-- +-- TOC entry 4134 (class 2606 OID 2493904) +-- Name: Poll Poll_teamId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Poll" + ADD CONSTRAINT "Poll_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES public."Team"(id); + + +-- +-- TOC entry 4220 (class 2606 OID 2495578) +-- Name: TeamInvitation fk_acceptedBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamInvitation" + ADD CONSTRAINT "fk_acceptedBy" FOREIGN KEY ("acceptedBy") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4151 (class 2606 OID 2494139) +-- Name: OrganizationApprovedDomain fk_addedByUserId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationApprovedDomain" + ADD CONSTRAINT "fk_addedByUserId" FOREIGN KEY ("addedByUserId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4230 (class 2606 OID 2495732) +-- Name: Notification fk_archivorUserId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_archivorUserId" FOREIGN KEY ("archivorUserId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4231 (class 2606 OID 2495757) +-- Name: Notification fk_authorId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_authorId" FOREIGN KEY ("authorId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4232 (class 2606 OID 2495722) +-- Name: Notification fk_changeAuthorId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_changeAuthorId" FOREIGN KEY ("changeAuthorId") REFERENCES public."TeamMember"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4233 (class 2606 OID 2495762) +-- Name: Notification fk_commentId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_commentId" FOREIGN KEY ("commentId") REFERENCES public."Comment"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4199 (class 2606 OID 2495312) +-- Name: Comment fk_createdBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Comment" + ADD CONSTRAINT "fk_createdBy" FOREIGN KEY ("createdBy") REFERENCES public."User"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4206 (class 2606 OID 2495410) +-- Name: NewMeeting fk_createdBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewMeeting" + ADD CONSTRAINT "fk_createdBy" FOREIGN KEY ("createdBy") REFERENCES public."User"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4224 (class 2606 OID 2495619) +-- Name: Task fk_createdBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "fk_createdBy" FOREIGN KEY ("createdBy") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4170 (class 2606 OID 2494890) +-- Name: RetroReflection fk_creatorId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflection" + ADD CONSTRAINT "fk_creatorId" FOREIGN KEY ("creatorId") REFERENCES public."User"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4200 (class 2606 OID 2495317) +-- Name: Comment fk_discussionId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Comment" + ADD CONSTRAINT "fk_discussionId" FOREIGN KEY ("discussionId") REFERENCES public."Discussion"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4225 (class 2606 OID 2495639) +-- Name: Task fk_discussionId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "fk_discussionId" FOREIGN KEY ("discussionId") REFERENCES public."Discussion"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4234 (class 2606 OID 2495772) +-- Name: Notification fk_discussionId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_discussionId" FOREIGN KEY ("discussionId") REFERENCES public."Discussion"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4128 (class 2606 OID 2495936) +-- Name: TaskEstimate fk_discussionId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TaskEstimate" + ADD CONSTRAINT "fk_discussionId" FOREIGN KEY ("discussionId") REFERENCES public."Discussion"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4235 (class 2606 OID 2495787) +-- Name: Notification fk_domainJoinRequestId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_domainJoinRequestId" FOREIGN KEY ("domainJoinRequestId") REFERENCES public."DomainJoinRequest"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4226 (class 2606 OID 2495624) +-- Name: Task fk_doneMeetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "fk_doneMeetingId" FOREIGN KEY ("doneMeetingId") REFERENCES public."NewMeeting"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4167 (class 2606 OID 2494858) +-- Name: EmbeddingsJobQueue fk_embeddingsMetadataId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."EmbeddingsJobQueue" + ADD CONSTRAINT "fk_embeddingsMetadataId" FOREIGN KEY ("embeddingsMetadataId") REFERENCES public."EmbeddingsMetadata"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4236 (class 2606 OID 2495742) +-- Name: Notification fk_evictorUserId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_evictorUserId" FOREIGN KEY ("evictorUserId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4153 (class 2606 OID 2494164) +-- Name: MeetingSeries fk_facilitatorId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSeries" + ADD CONSTRAINT "fk_facilitatorId" FOREIGN KEY ("facilitatorId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4207 (class 2606 OID 2495415) +-- Name: NewMeeting fk_facilitatorUserId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewMeeting" + ADD CONSTRAINT "fk_facilitatorUserId" FOREIGN KEY ("facilitatorUserId") REFERENCES public."User"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4140 (class 2606 OID 2494023) +-- Name: TeamMemberIntegrationAuth fk_integrationProvider; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMemberIntegrationAuth" + ADD CONSTRAINT "fk_integrationProvider" FOREIGN KEY ("providerId") REFERENCES public."IntegrationProvider"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4148 (class 2606 OID 2494118) +-- Name: IntegrationSearchQuery fk_integrationProvider; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationSearchQuery" + ADD CONSTRAINT "fk_integrationProvider" FOREIGN KEY ("providerId") REFERENCES public."IntegrationProvider"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4237 (class 2606 OID 2495747) +-- Name: Notification fk_invitationId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_invitationId" FOREIGN KEY ("invitationId") REFERENCES public."TeamInvitation"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4221 (class 2606 OID 2495573) +-- Name: TeamInvitation fk_invitedBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamInvitation" + ADD CONSTRAINT "fk_invitedBy" FOREIGN KEY ("invitedBy") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4165 (class 2606 OID 2494332) +-- Name: SAML fk_lastUpdatedBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SAML" + ADD CONSTRAINT "fk_lastUpdatedBy" FOREIGN KEY ("lastUpdatedBy") REFERENCES public."User"(id) ON DELETE SET DEFAULT; + + +-- +-- TOC entry 4215 (class 2606 OID 2495502) +-- Name: MeetingMember fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingMember" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4218 (class 2606 OID 2495526) +-- Name: MassInvitation fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MassInvitation" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4222 (class 2606 OID 2495568) +-- Name: TeamInvitation fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamInvitation" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4227 (class 2606 OID 2495629) +-- Name: Task fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4238 (class 2606 OID 2495712) +-- Name: Notification fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4124 (class 2606 OID 2495821) +-- Name: Discussion fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Discussion" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4135 (class 2606 OID 2495886) +-- Name: Poll fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Poll" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4171 (class 2606 OID 2495896) +-- Name: RetroReflection fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflection" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4161 (class 2606 OID 2495906) +-- Name: RetroReflectionGroup fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflectionGroup" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4168 (class 2606 OID 2495916) +-- Name: ScheduledJob fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ScheduledJob" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4129 (class 2606 OID 2495931) +-- Name: TaskEstimate fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TaskEstimate" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4143 (class 2606 OID 2495946) +-- Name: TeamPromptResponse fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamPromptResponse" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4174 (class 2606 OID 2495956) +-- Name: TimelineEvent fk_meetingId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TimelineEvent" + ADD CONSTRAINT "fk_meetingId" FOREIGN KEY ("meetingId") REFERENCES public."NewMeeting"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4208 (class 2606 OID 2495425) +-- Name: NewMeeting fk_meetingSeriesId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewMeeting" + ADD CONSTRAINT "fk_meetingSeriesId" FOREIGN KEY ("meetingSeriesId") REFERENCES public."MeetingSeries"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4122 (class 2606 OID 2495554) +-- Name: User fk_newFeatureId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."User" + ADD CONSTRAINT "fk_newFeatureId" FOREIGN KEY ("newFeatureId") REFERENCES public."NewFeature"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4178 (class 2606 OID 2494983) +-- Name: OrganizationUser fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUser" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4239 (class 2606 OID 2495737) +-- Name: Notification fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4138 (class 2606 OID 2495851) +-- Name: IntegrationProvider fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationProvider" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4152 (class 2606 OID 2495871) +-- Name: OrganizationApprovedDomain fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationApprovedDomain" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4118 (class 2606 OID 2495876) +-- Name: OrganizationUserAudit fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUserAudit" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4169 (class 2606 OID 2495911) +-- Name: ScheduledJob fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ScheduledJob" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4123 (class 2606 OID 2495941) +-- Name: Team fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Team" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4175 (class 2606 OID 2495951) +-- Name: TimelineEvent fk_orgId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TimelineEvent" + ADD CONSTRAINT "fk_orgId" FOREIGN KEY ("orgId") REFERENCES public."Organization"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4201 (class 2606 OID 2495362) +-- Name: ReflectPrompt fk_parentPromptId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ReflectPrompt" + ADD CONSTRAINT "fk_parentPromptId" FOREIGN KEY ("parentPromptId") REFERENCES public."ReflectPrompt"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4182 (class 2606 OID 2495061) +-- Name: TemplateScale fk_parentScaleId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScale" + ADD CONSTRAINT "fk_parentScaleId" FOREIGN KEY ("parentScaleId") REFERENCES public."TemplateScale"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4157 (class 2606 OID 2494255) +-- Name: MeetingTemplate fk_parentTemplateId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingTemplate" + ADD CONSTRAINT "fk_parentTemplateId" FOREIGN KEY ("parentTemplateId") REFERENCES public."MeetingTemplate"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4172 (class 2606 OID 2495891) +-- Name: RetroReflection fk_promptId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflection" + ADD CONSTRAINT "fk_promptId" FOREIGN KEY ("promptId") REFERENCES public."ReflectPrompt"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4162 (class 2606 OID 2495901) +-- Name: RetroReflectionGroup fk_promptId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflectionGroup" + ADD CONSTRAINT "fk_promptId" FOREIGN KEY ("promptId") REFERENCES public."ReflectPrompt"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4173 (class 2606 OID 2494895) +-- Name: RetroReflection fk_reflectionGroupId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."RetroReflection" + ADD CONSTRAINT "fk_reflectionGroupId" FOREIGN KEY ("reflectionGroupId") REFERENCES public."RetroReflectionGroup"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4240 (class 2606 OID 2495792) +-- Name: Notification fk_requestCreatedBy; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_requestCreatedBy" FOREIGN KEY ("requestCreatedBy") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4241 (class 2606 OID 2495752) +-- Name: Notification fk_responseId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_responseId" FOREIGN KEY ("responseId") REFERENCES public."TeamPromptResponse"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4242 (class 2606 OID 2495782) +-- Name: Notification fk_retroReflectionId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_retroReflectionId" FOREIGN KEY ("retroReflectionId") REFERENCES public."RetroReflection"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4166 (class 2606 OID 2494345) +-- Name: SAMLDomain fk_samlId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SAMLDomain" + ADD CONSTRAINT "fk_samlId" FOREIGN KEY ("samlId") REFERENCES public."SAML"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4185 (class 2606 OID 2495088) +-- Name: TemplateDimension fk_scaleId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateDimension" + ADD CONSTRAINT "fk_scaleId" FOREIGN KEY ("scaleId") REFERENCES public."TemplateScale"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4191 (class 2606 OID 2495211) +-- Name: MeetingSettings fk_selectedTemplateId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSettings" + ADD CONSTRAINT "fk_selectedTemplateId" FOREIGN KEY ("selectedTemplateId") REFERENCES public."MeetingTemplate"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4243 (class 2606 OID 2495777) +-- Name: Notification fk_senderUserId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_senderUserId" FOREIGN KEY ("senderUserId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4244 (class 2606 OID 2495727) +-- Name: Notification fk_taskId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_taskId" FOREIGN KEY ("taskId") REFERENCES public."Task"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4130 (class 2606 OID 2495921) +-- Name: TaskEstimate fk_taskId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TaskEstimate" + ADD CONSTRAINT "fk_taskId" FOREIGN KEY ("taskId") REFERENCES public."Task"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4139 (class 2606 OID 2494002) +-- Name: IntegrationProvider fk_team; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationProvider" + ADD CONSTRAINT fk_team FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4141 (class 2606 OID 2494028) +-- Name: TeamMemberIntegrationAuth fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMemberIntegrationAuth" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4154 (class 2606 OID 2494159) +-- Name: MeetingSeries fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSeries" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4163 (class 2606 OID 2494309) +-- Name: TeamMeetingTemplate fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMeetingTemplate" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4176 (class 2606 OID 2494939) +-- Name: TimelineEvent fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TimelineEvent" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4180 (class 2606 OID 2495014) +-- Name: TeamMember fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMember" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4183 (class 2606 OID 2495038) +-- Name: TemplateScale fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScale" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4186 (class 2606 OID 2495078) +-- Name: TemplateDimension fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateDimension" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4188 (class 2606 OID 2495137) +-- Name: SuggestedAction fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SuggestedAction" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4192 (class 2606 OID 2495206) +-- Name: MeetingSettings fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingSettings" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4193 (class 2606 OID 2495229) +-- Name: AgendaItem fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AgendaItem" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4195 (class 2606 OID 2495255) +-- Name: SlackAuth fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackAuth" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4197 (class 2606 OID 2495288) +-- Name: SlackNotification fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackNotification" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4202 (class 2606 OID 2495348) +-- Name: ReflectPrompt fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ReflectPrompt" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4204 (class 2606 OID 2495392) +-- Name: PushInvitation fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."PushInvitation" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4209 (class 2606 OID 2495420) +-- Name: NewMeeting fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewMeeting" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4216 (class 2606 OID 2495507) +-- Name: MeetingMember fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingMember" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4223 (class 2606 OID 2495583) +-- Name: TeamInvitation fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamInvitation" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4228 (class 2606 OID 2495634) +-- Name: Task fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4245 (class 2606 OID 2495767) +-- Name: Notification fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4126 (class 2606 OID 2495806) +-- Name: AtlassianAuth fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AtlassianAuth" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4146 (class 2606 OID 2495811) +-- Name: AzureDevOpsDimensionFieldMap fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AzureDevOpsDimensionFieldMap" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4125 (class 2606 OID 2495816) +-- Name: Discussion fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Discussion" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4120 (class 2606 OID 2495831) +-- Name: GitHubAuth fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitHubAuth" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4137 (class 2606 OID 2495836) +-- Name: GitHubDimensionFieldMap fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitHubDimensionFieldMap" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4145 (class 2606 OID 2495841) +-- Name: GitLabDimensionFieldMap fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitLabDimensionFieldMap" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4190 (class 2606 OID 2495846) +-- Name: Insight fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Insight" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4149 (class 2606 OID 2495856) +-- Name: IntegrationSearchQuery fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationSearchQuery" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4155 (class 2606 OID 2495861) +-- Name: JiraDimensionFieldMap fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraDimensionFieldMap" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4147 (class 2606 OID 2495866) +-- Name: JiraServerDimensionFieldMap fk_teamId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."JiraServerDimensionFieldMap" + ADD CONSTRAINT "fk_teamId" FOREIGN KEY ("teamId") REFERENCES public."Team"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4194 (class 2606 OID 2495234) +-- Name: AgendaItem fk_teamMemberId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AgendaItem" + ADD CONSTRAINT "fk_teamMemberId" FOREIGN KEY ("teamMemberId") REFERENCES public."TeamMember"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4219 (class 2606 OID 2495531) +-- Name: MassInvitation fk_teamMemberId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MassInvitation" + ADD CONSTRAINT "fk_teamMemberId" FOREIGN KEY ("teamMemberId") REFERENCES public."TeamMember"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4164 (class 2606 OID 2494314) +-- Name: TeamMeetingTemplate fk_templateId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMeetingTemplate" + ADD CONSTRAINT "fk_templateId" FOREIGN KEY ("templateId") REFERENCES public."MeetingTemplate"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4187 (class 2606 OID 2495083) +-- Name: TemplateDimension fk_templateId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateDimension" + ADD CONSTRAINT "fk_templateId" FOREIGN KEY ("templateId") REFERENCES public."MeetingTemplate"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4203 (class 2606 OID 2495353) +-- Name: ReflectPrompt fk_templateId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."ReflectPrompt" + ADD CONSTRAINT "fk_templateId" FOREIGN KEY ("templateId") REFERENCES public."MeetingTemplate"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4210 (class 2606 OID 2495430) +-- Name: NewMeeting fk_templateId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."NewMeeting" + ADD CONSTRAINT "fk_templateId" FOREIGN KEY ("templateId") REFERENCES public."MeetingTemplate"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4184 (class 2606 OID 2495053) +-- Name: TemplateScaleValue fk_templateScaleId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TemplateScaleValue" + ADD CONSTRAINT "fk_templateScaleId" FOREIGN KEY ("templateScaleId") REFERENCES public."TemplateScale"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4142 (class 2606 OID 2494018) +-- Name: TeamMemberIntegrationAuth fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMemberIntegrationAuth" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4144 (class 2606 OID 2494056) +-- Name: TeamPromptResponse fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamPromptResponse" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4150 (class 2606 OID 2494123) +-- Name: IntegrationSearchQuery fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."IntegrationSearchQuery" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4177 (class 2606 OID 2494934) +-- Name: TimelineEvent fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TimelineEvent" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4179 (class 2606 OID 2494978) +-- Name: OrganizationUser fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUser" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4181 (class 2606 OID 2495009) +-- Name: TeamMember fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TeamMember" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4189 (class 2606 OID 2495132) +-- Name: SuggestedAction fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SuggestedAction" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4196 (class 2606 OID 2495260) +-- Name: SlackAuth fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackAuth" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4198 (class 2606 OID 2495293) +-- Name: SlackNotification fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."SlackNotification" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4205 (class 2606 OID 2495387) +-- Name: PushInvitation fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."PushInvitation" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4217 (class 2606 OID 2495512) +-- Name: MeetingMember fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."MeetingMember" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4229 (class 2606 OID 2495644) +-- Name: Task fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Task" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE SET NULL; + + +-- +-- TOC entry 4246 (class 2606 OID 2495717) +-- Name: Notification fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."Notification" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4127 (class 2606 OID 2495801) +-- Name: AtlassianAuth fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."AtlassianAuth" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4121 (class 2606 OID 2495826) +-- Name: GitHubAuth fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GitHubAuth" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4119 (class 2606 OID 2495881) +-- Name: OrganizationUserAudit fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."OrganizationUserAudit" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- +-- TOC entry 4131 (class 2606 OID 2495926) +-- Name: TaskEstimate fk_userId; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."TaskEstimate" + ADD CONSTRAINT "fk_userId" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON DELETE CASCADE; + + +-- Completed on 2024-10-21 22:59:16 UTC + +-- +-- PostgreSQL database dump complete +-- + +`.execute(db) + + // pg_dump nulls out the search_path by default (for security) we must set it back or else future queries will fail + await sql`SELECT pg_catalog.set_config('search_path', 'public', false);`.execute(db) +} + +export async function down(db: Kysely): Promise {} diff --git a/packages/server/postgres/pgmConfig.js b/packages/server/postgres/pgmConfig.js deleted file mode 100644 index 9c11220aced..00000000000 --- a/packages/server/postgres/pgmConfig.js +++ /dev/null @@ -1,16 +0,0 @@ -const getPgSSL = require('./getPgSSL') - -const pgmConfig = { - user: process.env.POSTGRES_USER, - password: process.env.POSTGRES_PASSWORD, - host: process.env.POSTGRES_HOST, - port: process.env.POSTGRES_PORT, - database: process.env.POSTGRES_DB, - ssl: getPgSSL() ?? undefined, - tsconfig: 'packages/server/tsconfig.json', - 'migrations-dir': 'packages/server/postgres/migrations', - 'migrations-table': 'PgMigrations', - 'template-file-name': 'packages/server/postgres/migrationTemplate.ts' -} - -module.exports = pgmConfig diff --git a/packages/server/postgres/queries/getUserIdsToPause.ts b/packages/server/postgres/queries/getUserIdsToPause.ts deleted file mode 100644 index 3e396164f89..00000000000 --- a/packages/server/postgres/queries/getUserIdsToPause.ts +++ /dev/null @@ -1,13 +0,0 @@ -import getPg from '../getPg' -import catchAndLog from '../utils/catchAndLog' -import {getUserIdsToPauseQuery} from './generated/getUserIdsToPauseQuery' - -const getUserIdsToPause = async (activeThreshold: Date): Promise => { - return ( - (await catchAndLog(async () => - (await getUserIdsToPauseQuery.run({activeThreshold}, getPg())).map((user) => user.id) - )) ?? [] - ) -} - -export default getUserIdsToPause diff --git a/packages/server/postgres/utils/catchAndLog.ts b/packages/server/postgres/utils/catchAndLog.ts deleted file mode 100644 index 9369a8a2814..00000000000 --- a/packages/server/postgres/utils/catchAndLog.ts +++ /dev/null @@ -1,13 +0,0 @@ -import sendToSentry from '../../utils/sendToSentry' - -const catchAndLog = async any>(riskyFn: T) => { - try { - return (await riskyFn()) as ReturnType - } catch (e) { - const error = e instanceof Error ? e : new Error('catchAndLog failed') - sendToSentry(error, {tags: {migration: 'postgres'}}) - } - return null -} - -export default catchAndLog diff --git a/packages/server/postgres/utils/checkEqBase.ts b/packages/server/postgres/utils/checkEqBase.ts deleted file mode 100644 index 8d483673c6e..00000000000 --- a/packages/server/postgres/utils/checkEqBase.ts +++ /dev/null @@ -1,85 +0,0 @@ -import {RSelection} from 'rethinkdb-ts' -import getRethink from '../../database/rethinkDriver' -import getPg from '../getPg' - -interface DBDoc { - id: string - [key: string]: any -} -interface RethinkDoc extends DBDoc {} -interface PGDoc extends DBDoc {} - -interface Diff { - id: string | number - prop: string - rVal: string | number | boolean | undefined | null - pgVal: string | number | boolean | undefined | null -} - -export const checkRowCount = async (tableName: string) => { - const pg = getPg() - const r = await getRethink() - const [rCount, pgRes] = await Promise.all([ - r - .table(tableName as any) - .count() - .run(), - pg.query<{count: number}>(`SELECT COUNT(*) FROM "${tableName}";`) - ]) - const pgCount = Number(pgRes?.rows[0]?.count) - return rCount === pgCount - ? `Row count matches. ${rCount} in both DBs.` - : `Row count mismatch. RethinkDB: ${rCount}. PG: ${pgCount}` -} - -export async function checkTableEq( - rethinkQuery: (updatedAt: Date, id: string | number) => RSelection, - pgQuery: (ids: string[]) => Promise, - equalityMap: Record boolean>, - maxErrors: number | null | undefined -) { - maxErrors = maxErrors || 10 - const batchSize = 3000 - const errors = [] as Diff[] - const propsToCheck = Object.keys(equalityMap) - const r = await getRethink() - let curUpdatedDate = r.minval - let curId = r.minval - for (let i = 0; i < 1e6; i++) { - const rethinkRows = (await rethinkQuery(curUpdatedDate, curId) - .limit(batchSize) - .run()) as RethinkDoc[] - if (rethinkRows.length === 0) break - const lastRow = rethinkRows[rethinkRows.length - 1]! - curUpdatedDate = lastRow.updatedAt - curId = lastRow.id - const ids = rethinkRows.map((t) => t.id) - const pgRows = (await pgQuery(ids)) ?? [] - const pgRowsById = {} as {[key: string]: PGDoc} - pgRows.forEach((pgRow) => { - pgRowsById[pgRow.id] = pgRow - }) - - for (const rethinkRow of rethinkRows) { - const {id} = rethinkRow - const pgRow = pgRowsById[id] - - if (!pgRow) { - errors.push({id, prop: '', rVal: null, pgVal: null}) - if (errors.length >= maxErrors) return errors - continue - } - for (const prop of propsToCheck) { - const eqFn = equalityMap[prop] - const rVal = rethinkRow[prop] - const pgVal = pgRow[prop] - const isEqual = eqFn?.(rVal, pgVal) - if (!isEqual) { - errors.push({id, prop, rVal, pgVal}) - if (errors.length >= maxErrors) return errors - } - } - } - } - return errors -} diff --git a/packages/server/postgres/utils/rethinkEqualityFns.ts b/packages/server/postgres/utils/rethinkEqualityFns.ts deleted file mode 100644 index 0c003efbd57..00000000000 --- a/packages/server/postgres/utils/rethinkEqualityFns.ts +++ /dev/null @@ -1,131 +0,0 @@ -import isValidDate from 'parabol-client/utils/isValidDate' -import stringSimilarity from 'string-similarity' - -function sortObjectKeys(obj: any): any { - if (Array.isArray(obj)) { - // If it's an array, recurse into each element - return obj.map(sortObjectKeys) - } else if (obj !== null && typeof obj === 'object') { - if (obj instanceof Date) return obj - // If it's an object, sort the keys and recurse on each value - const sortedObj: {[key: string]: any} = {} - Object.keys(obj) - .sort() - .forEach((key) => { - sortedObj[key] = sortObjectKeys(obj[key]) - }) - return sortedObj - } else { - // If it's a primitive value, just return it - return obj - } -} - -export const defaultEqFn = (a: unknown, b: unknown) => { - if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime() - if (Array.isArray(a) && Array.isArray(b)) - return JSON.stringify(sortObjectKeys(a)) === JSON.stringify(sortObjectKeys(b)) - if (typeof a === 'object' && typeof b === 'object') - return JSON.stringify(sortObjectKeys(a)) === JSON.stringify(sortObjectKeys(b)) - return a === b -} -export const compareDateAlmostEqual = (rVal: unknown, pgVal: unknown) => { - if (isValidDate(rVal) && isValidDate(pgVal)) { - // Dates that are within 2 seconds of each other are considered equal - return Math.abs(rVal.getTime() - pgVal.getTime()) < 2000 - } - return false -} - -export const compareRealNumber = (rVal: unknown, pgVal: unknown) => { - if (typeof rVal !== 'number' || typeof pgVal !== 'number') return false - // real numbers are 4 bytes & guarantee 6-decimal places of precision - const answer = Math.abs(rVal - pgVal) < 1e-6 - return answer -} - -export const compareRValUndefinedAs = - (as: string | number | boolean | null | undefined) => (rVal: unknown, pgVal: unknown) => { - const normalizedRVal = rVal === undefined ? as : rVal - return defaultEqFn(normalizedRVal, pgVal) - } -export const compareRValUndefinedAsNull = (rVal: unknown, pgVal: unknown) => { - const normalizedRVal = rVal === undefined ? null : rVal - return defaultEqFn(normalizedRVal, pgVal) -} -export const compareRValUndefinedAsFalse = (rVal: unknown, pgVal: unknown) => { - const normalizedRVal = rVal === undefined ? false : rVal - return normalizedRVal === pgVal -} - -export const compareRValUndefinedAsZero = (rVal: unknown, pgVal: unknown) => { - const normalizedRVal = rVal === undefined ? 0 : rVal - return normalizedRVal === pgVal -} - -export const compareRValUndefinedAsEmptyArray = (rVal: unknown, pgVal: unknown) => { - const normalizedRVal = rVal === undefined ? [] : rVal - return defaultEqFn(normalizedRVal, pgVal) -} - -export const compareRValStringAsNumber = (rVal: unknown, pgVal: unknown) => { - const normalizedRVal = rVal ? Number(rVal) : null - return defaultEqFn(normalizedRVal, pgVal) -} - -export const compareRValOptionalPluckedObject = - (pluckFields: Record) => (rVal: unknown, pgVal: unknown) => { - if (!rVal && !pgVal) return true - const rValObj = rVal || {} - const pgValItem = pgVal || {} - return Object.keys(pluckFields).every((prop) => { - const eqFn = pluckFields[prop]! - const rValItemProp = rValObj[prop as keyof typeof rValObj] - const pgValItemProp = pgValItem[prop as keyof typeof pgValItem] - return eqFn(rValItemProp, pgValItemProp) - }) - } -export const compareRValOptionalPluckedArray = - (pluckFields: Record) => (rVal: unknown, pgVal: unknown) => { - const rValArray = Array.isArray(rVal) ? rVal : [] - if (!Array.isArray(pgVal) || pgVal.length !== rValArray.length) return false - let isEqual = true - rValArray.forEach((rValItem, idx) => { - const isEqualItem = Object.keys(pluckFields).every((prop) => { - const eqFn = pluckFields[prop]! - const rValItemProp = rValItem[prop] - const pgValItem = pgVal[idx] - const pgValItemProp = pgValItem[prop] - return eqFn(rValItemProp, pgValItemProp) - }) - if (!isEqualItem) { - isEqual = false - } - }) - return isEqual - } - -export const compareRValUndefinedAsNullAndTruncateRVal = - (length: number, similarity = 1) => - (rVal: unknown, pgVal: unknown) => { - const truncatedRVal = typeof rVal === 'string' ? rVal.slice(0, length) : rVal - const normalizedRVal = truncatedRVal === undefined ? null : truncatedRVal - if ( - typeof normalizedRVal === 'string' && - typeof pgVal === 'string' && - similarity && - similarity < 1 - ) { - if (normalizedRVal === pgVal) return true - const comparison = stringSimilarity.compareTwoStrings(normalizedRVal, pgVal) - return comparison >= similarity - } - return defaultEqFn(normalizedRVal, pgVal) - } - -export const compareOptionalPlaintextContent = (rVal: unknown, pgVal: unknown) => { - // old records don't have a plaintextContent, but we created that in new versions - return rVal === undefined - ? true - : compareRValUndefinedAsNullAndTruncateRVal(2000, 0.19)(rVal, pgVal) -} diff --git a/packages/server/server.ts b/packages/server/server.ts index c17b262568b..7a97eadb084 100644 --- a/packages/server/server.ts +++ b/packages/server/server.ts @@ -1,5 +1,4 @@ import tracer from 'dd-trace' -import {r} from 'rethinkdb-ts' import uws, {SHARED_COMPRESSOR} from 'uWebSockets.js' import sleep from '../client/utils/sleep' import ICSHandler from './ICSHandler' @@ -32,12 +31,6 @@ tracer.init({ }) tracer.use('ioredis').use('http').use('pg') -if (!__PRODUCTION__) { - process.on('SIGINT', async () => { - r.getPoolMaster()?.drain() - }) -} - process.on('SIGTERM', async (signal) => { console.log( `Server ID: ${process.env.SERVER_ID}. Kill signal received: ${signal}, starting graceful shutdown.` diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index bc89d53cbbe..33bca7f724a 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -14,8 +14,6 @@ "exclude": [ "**/node_modules", "types/githubTypes.ts", - "postgres/migrationTemplate.ts", - "database/migrations/**/*", "postgres/migrations/**/*", "graphql/intranetSchema/sdl/resolverTypes.ts", "billing/debug.ts" diff --git a/pm2.dev.config.js b/pm2.dev.config.js index 6cd457059ef..dcc5d86dd63 100644 --- a/pm2.dev.config.js +++ b/pm2.dev.config.js @@ -48,9 +48,13 @@ module.exports = { script: 'scripts/hmrServer.js' }, { - name: 'DB Migrations', - script: 'scripts/runMigrations.js', - // once this completes, it will exit + name: 'Flush Redis', + script: 'scripts/flushRedis.js', + autorestart: false + }, + { + name: 'PG Migrations', + script: 'yarn kysely migrate:latest', autorestart: false }, { diff --git a/scripts/flushRedis.js b/scripts/flushRedis.js new file mode 100644 index 00000000000..e4b599053b3 --- /dev/null +++ b/scripts/flushRedis.js @@ -0,0 +1,16 @@ +require('./webpack/utils/dotenv') +const Redis = require('ioredis') + +const clearRedis = async () => { + // Files run by pm2 must be pure JS (not .ts). + // The RedisInstance (TLS) logic is written in .ts, so we can't use TLS here + const redis = new Redis(process.env.REDIS_URL, {connectionName: 'devRedis'}) + await redis.flushall() + redis.disconnect() +} + +const runMigrations = async () => { + await clearRedis() +} + +runMigrations() diff --git a/scripts/migrate.js b/scripts/migrate.js deleted file mode 100644 index 9720cb50189..00000000000 --- a/scripts/migrate.js +++ /dev/null @@ -1,40 +0,0 @@ -require('./webpack/utils/dotenv') -const path = require('path') -const migrate = require('rethinkdb-ts-migrate') -const {parse} = require('url') -const getProjectRoot = require('./webpack/utils/getProjectRoot') -const fs = require('fs') - -const startMigration = async (direction = 'up') => { - // migrating up goes all the way, migrating down goes down by 1 - const all = direction === 'up' - if (process.env.NODE_ENV === 'test') { - console.log('NODE_ENV is test, loading .env.test...') - } - const PROJECT_ROOT = getProjectRoot() - const DB_ROOT = path.join(PROJECT_ROOT, 'packages/server/database') - const {hostname, port, path: urlPath} = parse(process.env.RETHINKDB_URL) - process.env.host = hostname - process.env.port = port - process.env.db = urlPath.slice(1) - process.env.r = process.cwd() - if (direction === 'up') { - const files = fs.readdirSync(path.join(DB_ROOT, 'migrations')) - if (files.length !== 154) - throw new Error('New migrations must live in the postgres/migrations directory') - } - - try { - await migrate[direction]({all, root: DB_ROOT}) - } catch (e) { - console.error('Migration error', e) - } -} - -if (require.main === module) { - const [, , direction = 'up'] = process.argv - const dir = direction === 'up' || direction === 'down' ? direction : undefined - startMigration(dir) -} - -module.exports = startMigration diff --git a/scripts/runMigrations.js b/scripts/runMigrations.js deleted file mode 100644 index e352362e3d7..00000000000 --- a/scripts/runMigrations.js +++ /dev/null @@ -1,43 +0,0 @@ -require('./webpack/utils/dotenv') -const pgMigrate = require('node-pg-migrate').default -const cliPgmConfig = require('../packages/server/postgres/pgmConfig') -const path = require('path') -const Redis = require('ioredis') - -const migrateRethinkDB = async () => { - return require('./migrate')() -} - -const migratePG = async () => { - const programmaticPgmConfig = { - dbClient: cliPgmConfig, - dir: path.join(__dirname, '..', cliPgmConfig['migrations-dir']), - direction: 'up', - migrationsTable: cliPgmConfig['migrations-table'] - } - return pgMigrate(programmaticPgmConfig) -} - -const clearRedis = async () => { - // Files run by pm2 must be pure JS (not .ts). - // The RedisInstance (TLS) logic is written in .ts, so we can't use TLS here - const redis = new Redis(process.env.REDIS_URL, {connectionName: 'devRedis'}) - await redis.flushall() - redis.disconnect() -} - -const migrateDBs = async () => { - // RethinkDB must be run first because - // Some PG migrations depemd on the latest state of RethinkDB - await migrateRethinkDB() - return migratePG() -} - -const runMigrations = async () => { - await Promise.all([clearRedis(), migrateDBs()]) - setInterval(() => { - /* keep process from exiting to keep PM2 quiet */ - }, 1 << 30) -} - -runMigrations() diff --git a/scripts/toolboxSrc/pgMigrateRunner.ts b/scripts/toolboxSrc/pgMigrateRunner.ts deleted file mode 100644 index b8949fb122a..00000000000 --- a/scripts/toolboxSrc/pgMigrateRunner.ts +++ /dev/null @@ -1,244 +0,0 @@ -// This is copied almost entirely from pg-migrate -// The only difference is this accepts a list of migrations instead of using a dynamic require -import Db, {DBConnection} from 'node-pg-migrate/dist/db' -import {Migration, RunMigration} from 'node-pg-migrate/dist/migration' -import { - Logger, MigrationBuilderActions, - MigrationDirection, RunnerOption, RunnerOptionClient, - RunnerOptionUrl -} from 'node-pg-migrate/dist/types' -import {createSchemalize, getMigrationTableSchema, getSchemas} from 'node-pg-migrate/dist/utils' - -// Random but well-known identifier shared by all instances of node-pg-migrate -const PG_MIGRATE_LOCK_ID = 7241865325823964 - -const idColumn = 'id' -const nameColumn = 'name' -const runOnColumn = 'run_on' - -type OptsWithMigs = RunnerOption & {migrations: Record} -const loadMigrations = async (db: DBConnection, options: OptsWithMigs, logger: Logger) => { - try { - const {migrations} = options - // let shorthands: ColumnDefinitions = {} - return Object.entries(migrations).map(([filePath, actions]) => { - return new Migration( - db, - filePath, - actions, - options, - { - // ...shorthands, - }, - logger, - ) - }) - .sort((m1, m2) => { - const compare = m1.timestamp - m2.timestamp - if (compare !== 0) return compare - return m1.name.localeCompare(m2.name) - }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (err: any) { - throw new Error(`Can't get migration files: ${err.stack}`) - } -} - -const lock = async (db: DBConnection): Promise => { - const [result] = await db.select(`select pg_try_advisory_lock(${PG_MIGRATE_LOCK_ID}) as "lockObtained"`) - if (!result.lockObtained) { - throw new Error('Another migration is already running') - } -} - -const unlock = async (db: DBConnection): Promise => { - const [result] = await db.select(`select pg_advisory_unlock(${PG_MIGRATE_LOCK_ID}) as "lockReleased"`) - - if (!result.lockReleased) { - throw new Error('Failed to release migration lock') - } -} - -const ensureMigrationsTable = async (db: DBConnection, options: RunnerOption): Promise => { - try { - const schema = getMigrationTableSchema(options) - const {migrationsTable} = options - const fullTableName = createSchemalize( - Boolean(options.decamelize), - true, - )({ - schema, - name: migrationsTable, - }) - - const migrationTables = await db.select( - `SELECT table_name FROM information_schema.tables WHERE table_schema = '${schema}' AND table_name = '${migrationsTable}'`, - ) - - if (migrationTables && migrationTables.length === 1) { - const primaryKeyConstraints = await db.select( - `SELECT constraint_name FROM information_schema.table_constraints WHERE table_schema = '${schema}' AND table_name = '${migrationsTable}' AND constraint_type = 'PRIMARY KEY'`, - ) - if (!primaryKeyConstraints || primaryKeyConstraints.length !== 1) { - await db.query(`ALTER TABLE ${fullTableName} ADD PRIMARY KEY (${idColumn})`) - } - } else { - await db.query( - `CREATE TABLE ${fullTableName} ( ${idColumn} SERIAL PRIMARY KEY, ${nameColumn} varchar(255) NOT NULL, ${runOnColumn} timestamp NOT NULL)`, - ) - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (err: any) { - throw new Error(`Unable to ensure migrations table: ${err.stack}`) - } -} - -const getRunMigrations = async (db: DBConnection, options: RunnerOption) => { - const schema = getMigrationTableSchema(options) - const {migrationsTable} = options - const fullTableName = createSchemalize( - Boolean(options.decamelize), - true, - )({ - schema, - name: migrationsTable, - }) - return db.column(nameColumn, `SELECT ${nameColumn} FROM ${fullTableName} ORDER BY ${runOnColumn}, ${idColumn}`) -} - -const getMigrationsToRun = (options: RunnerOption, runNames: string[], migrations: Migration[]): Migration[] => { - if (options.direction === 'down') { - const downMigrations: Array = runNames - .filter((migrationName) => !options.file || options.file === migrationName) - .map((migrationName) => migrations.find(({name}) => name === migrationName) || migrationName) - const {count = 1} = options - const toRun = ( - options.timestamp - ? downMigrations.filter((migration) => typeof migration === 'object' && migration.timestamp >= count) - : downMigrations.slice(-Math.abs(count)) - ).reverse() - const deletedMigrations = toRun.filter((migration): migration is string => typeof migration === 'string') - if (deletedMigrations.length) { - const deletedMigrationsStr = deletedMigrations.join(', ') - throw new Error(`Definitions of migrations ${deletedMigrationsStr} have been deleted.`) - } - return toRun as Migration[] - } - const upMigrations = migrations.filter( - ({name}) => runNames.indexOf(name) < 0 && (!options.file || options.file === name), - ) - const {count = Infinity} = options - return options.timestamp - ? upMigrations.filter(({timestamp}) => timestamp <= count) - : upMigrations.slice(0, Math.abs(count)) -} - -const checkOrder = (runNames: string[], migrations: Migration[]) => { - const len = Math.min(runNames.length, migrations.length) - for (let i = 0; i < len; i += 1) { - const runName = runNames[i] - const migrationName = migrations[i].name - if (runName !== migrationName) { - throw new Error(`Not run migration ${migrationName} is preceding already run migration ${runName}`) - } - } -} - -const runMigrations = (toRun: Migration[], method: 'markAsRun' | 'apply', direction: MigrationDirection) => - toRun.reduce( - (promise: Promise, migration) => promise.then(() => migration[method](direction)), - Promise.resolve(), - ) - -const getLogger = ({log, logger, verbose}: RunnerOption): Logger => { - let loggerObject: Logger = console - if (typeof logger === 'object') { - loggerObject = logger - } else if (typeof log === 'function') { - loggerObject = {debug: log, info: log, warn: log, error: log} - } - return verbose - ? loggerObject - : { - debug: undefined, - info: loggerObject.info.bind(loggerObject), - warn: loggerObject.warn.bind(loggerObject), - error: loggerObject.error.bind(loggerObject), - } -} - -export default async (options: OptsWithMigs): Promise => { - const logger = getLogger(options) - const db = Db((options as RunnerOptionClient).dbClient || (options as RunnerOptionUrl).databaseUrl, logger) - try { - await db.createConnection() - - if (!options.noLock) { - await lock(db) - } - - if (options.schema) { - const schemas = getSchemas(options.schema) - if (options.createSchema) { - await Promise.all(schemas.map((schema) => db.query(`CREATE SCHEMA IF NOT EXISTS "${schema}"`))) - } - await db.query(`SET search_path TO ${schemas.map((s) => `"${s}"`).join(', ')}`) - } - if (options.migrationsSchema && options.createMigrationsSchema) { - await db.query(`CREATE SCHEMA IF NOT EXISTS "${options.migrationsSchema}"`) - } - - await ensureMigrationsTable(db, options) - - const [migrations, runNames] = await Promise.all([ - loadMigrations(db, options, logger), - getRunMigrations(db, options), - ]) - - if (options.checkOrder) { - checkOrder(runNames, migrations) - } - - const toRun: Migration[] = getMigrationsToRun(options, runNames, migrations) - - if (!toRun.length) { - logger.info('PostgreSQL - No migrations to run!') - return [] - } - - // TODO: add some fancy colors to logging - logger.info('> Migrating files:') - toRun.forEach((m) => { - logger.info(`> - ${m.name}`) - }) - - if (options.fake) { - await runMigrations(toRun, 'markAsRun', options.direction) - } else if (options.singleTransaction) { - await db.query('BEGIN') - try { - await runMigrations(toRun, 'apply', options.direction) - await db.query('COMMIT') - } catch (err) { - logger.warn('> Rolling back attempted migration ...') - await db.query('ROLLBACK') - throw err - } - } else { - await runMigrations(toRun, 'apply', options.direction) - } - - return toRun.map((m) => ({ - path: m.path, - name: m.name, - timestamp: m.timestamp, - })) - } finally { - if (db.connected()) { - if (!options.noLock) { - await unlock(db).catch((error) => logger.warn(error.message)) - } - db.close() - } - } -} diff --git a/scripts/toolboxSrc/renameDB.ts b/scripts/toolboxSrc/renameDB.ts deleted file mode 100644 index f9166c8fcef..00000000000 --- a/scripts/toolboxSrc/renameDB.ts +++ /dev/null @@ -1,32 +0,0 @@ -import getRethink from '../../packages/server/database/rethinkDriver' - -async function renameDB() { - const FROM = process.argv[2] || 'orgBackup' - const TO = process.argv[3] || 'actionDevelopment' - const r = await getRethink() - try { - await r.dbDrop(TO).run() - } catch (e) { - // empty - } - await r.dbCreate(TO).run() - const list = await r - .db(FROM) - .tableList() - .run() - const promises = list.map((table) => - r - .db(FROM) - .table(table) - .config() - .update({ - db: TO - } as any) - .run() - ) - await Promise.all(promises) - console.log('Move to actionDevelopment complete!') - r.getPoolMaster().drain() -} - -renameDB() diff --git a/scripts/toolboxSrc/rethinkMigrateRunner.ts b/scripts/toolboxSrc/rethinkMigrateRunner.ts deleted file mode 100644 index 5272db2184c..00000000000 --- a/scripts/toolboxSrc/rethinkMigrateRunner.ts +++ /dev/null @@ -1,205 +0,0 @@ -// This is copied almost entirely from rethinkdb-migrate -// The only difference is this accepts a list of migrations instead of using a dynamic require -import chalk from 'chalk' -import nconf from 'nconf' -import * as path from 'path' -import {r, R} from 'rethinkdb-ts' - -require('sucrase/register') - -const MIGRATION_TABLE_NAME = '_migrations' -type MigrationFn = (r: R) => void - -interface MigrationFile { - up: MigrationFn - down: MigrationFn -} - -/* - Read config from - - arguments - - environment variables - - /database.json - */ -type Unpromise = T extends (...args: any[]) => Promise ? U : T - -const getConfig = async (root: string) => { - nconf - .argv() - .env() - .file({file: path.join(root, 'database.json')}) - return { - host: nconf.get('host'), - port: nconf.get('port'), - user: nconf.get('user') || 'admin', - password: nconf.get('password') || '', - db: nconf.get('db'), - discovery: Boolean(nconf.get('discovery')) || false, - timeout: nconf.get('timeout') || 5 * 60, - authKey: nconf.get('authKey'), - ssl: nconf.get('ssl'), - } -} -type Config = Unpromise - -/* - Connect to db - If db does not yet exist, create it - */ -async function connectToDb(config: Config) { - await r.connectPool(config) - const dbs = await r.dbList().run() - if (!dbs.includes(config.db)) { - await r.dbCreate(config.db).run() - } - const tables = await r.tableList().run() - if (!tables.includes(MIGRATION_TABLE_NAME)) { - await r.tableCreate(MIGRATION_TABLE_NAME).run() - await r.table(MIGRATION_TABLE_NAME).indexCreate('timestamp').run() - await r.table(MIGRATION_TABLE_NAME).indexWait().run() - } - await r.db(config.db).wait({waitFor: 'ready_for_writes'}).run() -} - -/* - Compares completed migrations to files on disk - Returns the migrations scripts with a timestamp newer than last - completed migration in db. - TODO: Change so that all non run migration scripts are returned - */ -async function getMigrationsExcept( - completedMigration: Migration | undefined, - migrations: Record, - numToApply: -1 | 1, -) { - const allMigrations = Object.entries(migrations).map(([filename, code]) => { - // const tsix = filename.indexOf('-') - const [timestamp, name] = filename.split('-') - return { - name, - timestamp, - filename, - code - } - }).filter((migration) => { - return completedMigration ? migration.timestamp > completedMigration.timestamp : true - }) - return numToApply !== -1 ? allMigrations.slice(0, numToApply) : allMigrations -} - -/* - Takes a list of migration file paths and requires them - */ -function requireMigrations(runMigrations: Migration[], migrations: Record) { - return runMigrations.map(function (migration) { - const filename = migration.timestamp + '-' + migration.name - const filenames = Object.keys(migrations) - const matchingFilename = filenames.find((name) => name.includes(migration.timestamp))! - return { - ...migration, - filename, - code: migrations[matchingFilename] - } - }) -} - -/* - Run all new up migrations - */ - -interface Params { - root?: string - all?: boolean - migrations: Record -} - -interface Migration { - id: string - name: string - timestamp: string -} - -export async function up(params: Params): Promise { - const {all, root, migrations: inMigrations} = params - const rootDir = root || process.cwd() - await connectToDb(await getConfig(rootDir)) - const completedMigrations = await r - .table(MIGRATION_TABLE_NAME) - .orderBy({index: 'timestamp'}) - .run() - const latest = completedMigrations[completedMigrations.length - 1] - const numToApply = all ? -1 : 1 - const migrations = await getMigrationsExcept(latest, inMigrations, numToApply) - if (migrations.length < 1) { - logInfo('No new migrations') - await r.getPoolMaster()?.drain() - return - } - for (let i = 0; i < migrations.length; i++) { - const migration = migrations[i] - logInfo(chalk.black.bgGreen(' ↑ up ↑ '), migration.timestamp, chalk.yellow(migration.name)) - const {name, timestamp} = migration - try { - await migration.code.up(r) - } catch (e) { - logError(`Migration failed: ${name}`, e as any) - await r.getPoolMaster()?.drain() - return - } - await r.table(MIGRATION_TABLE_NAME).insert({name, timestamp}).run() - } - logInfo('Migration Successful') - await r.getPoolMaster()?.drain() -} - -/* - Rollback one or all migrations - */ -export async function down(params: Params): Promise { - const {all, root, migrations: inMigrations} = params - const rootDir = root || process.cwd() - await connectToDb(await getConfig(rootDir)) - const completedMigrations = await r - .table(MIGRATION_TABLE_NAME) - .orderBy({index: 'timestamp'}) - .run() - if (completedMigrations.length === 0) { - logInfo('No new migrations') - await r.getPoolMaster()?.drain() - return - } - const migrationsToRollBack = all - ? completedMigrations.reverse() - : [completedMigrations[completedMigrations.length - 1]] - const migrations = requireMigrations(migrationsToRollBack, inMigrations) - for (let i = 0; i < migrations.length; i++) { - const migration = migrations[i] - logInfo(chalk.black.bgYellow(' ↓ down ↓ '), migration.timestamp, chalk.yellow(migration.name)) - const {name} = migration - try { - await migration.code.down(r) - } catch (e) { - logError(`Migration failed: ${name}`, e as any) - await r.getPoolMaster()?.drain() - return - } - await r.table(MIGRATION_TABLE_NAME).get(migration.id).delete().run() - } - logInfo('Migration successful') - await r.getPoolMaster()?.drain() -} - -function logInfo(...args: any[]) { - args.unshift(chalk.blue('[migrate-rethinkdb]')) - console.log(args.join(' ')) -} - -function logError(txt: string, error: Error) { - console.error(chalk.red('[migrate-rethinkdb] ') + txt) - if (error) { - console.error(error) - if (error.stack) { - console.error(error.stack) - } - } -} diff --git a/scripts/toolboxSrc/softenDurability.ts b/scripts/toolboxSrc/softenDurability.ts deleted file mode 100644 index 70a98246aec..00000000000 --- a/scripts/toolboxSrc/softenDurability.ts +++ /dev/null @@ -1,20 +0,0 @@ -import getRethink from '../../packages/server/database/rethinkDriver' -export default async function softenDurability() { - const r = await getRethink() - console.log('Softening durability for faster tests') - const tables = await r.tableList().run() - const promises = tables.map((table) => - r - .table(table) - .config() - .update({ - durability: 'soft' - } as any) - .run() - ) - await Promise.all(promises) - console.log('Table durability set to "soft"') - process.exit() -} - -softenDurability() diff --git a/scripts/toolboxSrc/standaloneMigrations.ts b/scripts/toolboxSrc/standaloneMigrations.ts index 97ea91bd2a1..092e0cf55ec 100644 --- a/scripts/toolboxSrc/standaloneMigrations.ts +++ b/scripts/toolboxSrc/standaloneMigrations.ts @@ -1,36 +1,12 @@ // Should roughly match runMigrations.js except it isn't run in PM2 in dev // This file is bundled by webpack into a small migrate.js file which includes all migration files & their deps // It is used by PPMIs who are only provided with the bundles +import {Migrator} from 'kysely' import path from 'path' -import {r} from 'rethinkdb-ts' -import {parse} from 'url' -import cliPgmConfig from '../../packages/server/postgres/pgmConfig' +import migratorConfig from '../../.config/kysely.config' +import getKysely from '../../packages/server/postgres/getKysely' import '../webpack/utils/dotenv' import pgEnsureExtensions from './pgEnsureExtensions' -import pgMigrate from './pgMigrateRunner' -import * as rethinkMigrate from './rethinkMigrateRunner' - -const migrateRethinkDB = async () => { - console.log('👴 RethinkDB Migration Started') - const {hostname, port, path: urlPath} = parse(process.env.RETHINKDB_URL!) - process.env.host = hostname! - process.env.port = port! - process.env.db = urlPath!.slice(1) - process.env.r = process.cwd() - const context = (require as any).context( - '../../packages/server/database/migrations', - false, - /.(js|ts)$/ - ) - const collector = {} - context.keys().forEach((relativePath) => { - const {name} = path.parse(relativePath) - collector[name] = context(relativePath) - }) - await rethinkMigrate.up({all: true, migrations: collector}) - console.log('👴 RethinkDB Migration Complete') -} - const migratePG = async () => { console.log('🐘 Postgres Migration Started') await pgEnsureExtensions() @@ -42,32 +18,40 @@ const migratePG = async () => { false, /.ts$/ ) - const collector = {} - context.keys().forEach((relativePath) => { - const {name, ext} = path.parse(relativePath) - const key = `${cliPgmConfig['migrations-dir']}/${name}${ext}` - collector[key] = context(relativePath) + const collector: Record = {} + context.keys().forEach((relativePath: any) => { + const {name} = path.parse(relativePath) + collector[name] = context(relativePath) + }) + const pg = getKysely() + const migrator = new Migrator({ + ...migratorConfig['migrations'], + db: pg, + provider: { + async getMigrations() { + return collector + } + } + }) + const {error, results} = await migrator.migrateToLatest() + + results?.forEach((it) => { + if (it.status === 'Success') { + console.log(` ✅ Migration: ${it.migrationName}`) + } else if (it.status === 'Error') { + console.error(` ⛔️ Migration: ${it.migrationName}`) + } }) - const programmaticPgmConfig = { - dbClient: cliPgmConfig, - dir: path.join(__dirname, '..', cliPgmConfig['migrations-dir']), - direction: 'up', - migrationsTable: cliPgmConfig['migrations-table'], - migrations: collector - } - await pgMigrate(programmaticPgmConfig as any) - console.log('🐘 Postgres Migration Complete') -} -const migrateDBs = async () => { - // RethinkDB must be run first because - // Some PG migrations depemd on the latest state of RethinkDB - await migrateRethinkDB() - await migratePG() - await r.getPoolMaster()?.drain() + if (error) { + console.log('🐘 Postgres Migration Failed') + console.error(error) + } else { + console.log('🐘 Postgres Migration Complete') + } } // If called via CLI -if (require.main === module) migrateDBs() +if (require.main === module) migratePG() -export default migrateDBs +export default migratePG diff --git a/scripts/webpack/toolbox.config.js b/scripts/webpack/toolbox.config.js index bb3913a2b78..254db481b3b 100644 --- a/scripts/webpack/toolbox.config.js +++ b/scripts/webpack/toolbox.config.js @@ -22,9 +22,7 @@ module.exports = { entry: { assignSURole: [DOTENV, path.join(TOOLBOX_SRC, 'assignSURole.ts')], pgRestore: [DOTENV, path.join(TOOLBOX_SRC, 'pgRestore.ts')], - renameDB: [DOTENV, path.join(TOOLBOX_SRC, 'renameDB.ts')], setIsEnterprise: [DOTENV, path.join(TOOLBOX_SRC, 'setIsEnterprise.ts')], - softenDurability: [DOTENV, path.join(TOOLBOX_SRC, 'softenDurability.ts')], updateSchema: [DOTENV, path.join(SERVER_ROOT, 'utils', 'updateGQLSchema.ts')] }, output: { diff --git a/scripts/webpack/utils/transformRules.js b/scripts/webpack/utils/transformRules.js index e6bc0c9dadf..379897709e2 100644 --- a/scripts/webpack/utils/transformRules.js +++ b/scripts/webpack/utils/transformRules.js @@ -56,10 +56,7 @@ const transformRules = (projectRoot, isProd) => { loader: '@sucrase/webpack-loader', options: { production: isProd, - // imports is needed for old JS RethinkDB migration files - // otherwise exports.up is ignored when an import statement is there - // can remove when they're gone - transforms: ['jsx', 'typescript', 'imports'] + transforms: ['jsx', 'typescript'] } } }, diff --git a/yarn.lock b/yarn.lock index d6e21700c55..434ba9a4105 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4040,6 +4040,126 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== +"@esbuild/aix-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" + integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== + +"@esbuild/android-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" + integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== + +"@esbuild/android-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" + integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== + +"@esbuild/android-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" + integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== + +"@esbuild/darwin-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" + integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== + +"@esbuild/darwin-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" + integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== + +"@esbuild/freebsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" + integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== + +"@esbuild/freebsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" + integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== + +"@esbuild/linux-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" + integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== + +"@esbuild/linux-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" + integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== + +"@esbuild/linux-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" + integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== + +"@esbuild/linux-loong64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" + integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== + +"@esbuild/linux-mips64el@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" + integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== + +"@esbuild/linux-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" + integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== + +"@esbuild/linux-riscv64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" + integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== + +"@esbuild/linux-s390x@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" + integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== + +"@esbuild/linux-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" + integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== + +"@esbuild/netbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" + integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== + +"@esbuild/openbsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" + integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== + +"@esbuild/openbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" + integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== + +"@esbuild/sunos-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" + integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== + +"@esbuild/win32-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" + integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== + +"@esbuild/win32-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" + integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== + +"@esbuild/win32-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" + integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -9093,7 +9213,7 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== -"@types/minimist@^1.2.0", "@types/minimist@^1.2.2": +"@types/minimist@^1.2.0": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== @@ -9179,14 +9299,14 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb" integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g== -"@types/pg@^8.0.0": - version "8.6.3" - resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.6.3.tgz#eacfd5954752dd64d93d71d639e8c5b1f3bd3f22" - integrity sha512-P0RrXJcw1hPS+KF0nBCC3FEEdZBfRsHbYtAzbY2QTc0gC4jFQvjQxIKXs0X/NgPhPI4DbAzdeW7WMCjaWjT7Pg== +"@types/pg@^8.11.10": + version "8.11.10" + resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.11.10.tgz#b8fb2b2b759d452fe3ec182beadd382563b63291" + integrity sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg== dependencies: "@types/node" "*" pg-protocol "*" - pg-types "^2.2.0" + pg-types "^4.0.1" "@types/prettier@^2.1.5": version "2.4.2" @@ -9908,6 +10028,11 @@ acorn@^8.12.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.12.1: + version "8.13.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" + integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== + acorn@^8.4.1: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" @@ -10285,11 +10410,6 @@ asn1js@^3.0.1, asn1js@^3.0.5: pvutils "^1.1.3" tslib "^2.4.0" -assert-options@0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/assert-options/-/assert-options-0.8.0.tgz#cf71882534d23d3027945bc7462e20d3d3682380" - integrity sha512-qSELrEaEz4sGwTs4Qh+swQkjiHAysC4rot21+jzXU86dJzNG+FDqBzyS3ohSoTRf4ZLA3FSwxQdiuNl5NXUtvA== - assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" @@ -10905,6 +11025,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c12@^1.8.0: + version "1.11.2" + resolved "https://registry.yarnpkg.com/c12/-/c12-1.11.2.tgz#f8a1e30c10f4b273894a1bcb6944f76c15b56717" + integrity sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew== + dependencies: + chokidar "^3.6.0" + confbox "^0.1.7" + defu "^6.1.4" + dotenv "^16.4.5" + giget "^1.2.3" + jiti "^1.21.6" + mlly "^1.7.1" + ohash "^1.1.3" + pathe "^1.1.2" + perfect-debounce "^1.0.0" + pkg-types "^1.2.0" + rc9 "^2.1.2" + cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" @@ -11023,16 +11161,6 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" -camelcase-keys@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-7.0.1.tgz#5a57e6dfb3f6c7929dad15599ee4476a7e9a3b2d" - integrity sha512-P331lEls98pW8JLyodNWfzuz91BEDVA4VpW2/SwXnyv2K495tq1N777xzDbFgnEigfA7UIY0xa6PwR/H9jijjA== - dependencies: - camelcase "^6.2.0" - map-obj "^4.1.0" - quick-lru "^5.1.1" - type-fest "^1.2.1" - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -11257,6 +11385,13 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== +citty@^0.1.4, citty@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.6.tgz#0f7904da1ed4625e1a9ea7e0fa780981aab7c5e4" + integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ== + dependencies: + consola "^3.2.3" + cjs-module-lexer@^1.0.0, cjs-module-lexer@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" @@ -11646,6 +11781,11 @@ concurrently@^8.0.1: tree-kill "^1.2.2" yargs "^17.7.1" +confbox@^0.1.7, confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== + config-chain@^1.1.12: version "1.1.13" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" @@ -11659,6 +11799,11 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== +consola@^3.2.0, consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -12240,11 +12385,6 @@ decamelize@^1.1.0, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decamelize@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.1.tgz#db11a92e58c741ef339fb0a2868d8a06a9a7b1e9" - integrity sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA== - decimal.js@^10.4.1: version "10.4.2" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" @@ -12347,6 +12487,11 @@ defined@^1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + degenerator@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5" @@ -12409,6 +12554,11 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +destr@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.3.tgz#7f9e97cb3d16dbdca7be52aca1644ce402cfe449" + integrity sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -12997,6 +13147,36 @@ es6-weak-map@^2.0.3: es6-iterator "^2.0.3" es6-symbol "^3.1.1" +esbuild@~0.23.0: + version "0.23.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" + integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.23.1" + "@esbuild/android-arm" "0.23.1" + "@esbuild/android-arm64" "0.23.1" + "@esbuild/android-x64" "0.23.1" + "@esbuild/darwin-arm64" "0.23.1" + "@esbuild/darwin-x64" "0.23.1" + "@esbuild/freebsd-arm64" "0.23.1" + "@esbuild/freebsd-x64" "0.23.1" + "@esbuild/linux-arm" "0.23.1" + "@esbuild/linux-arm64" "0.23.1" + "@esbuild/linux-ia32" "0.23.1" + "@esbuild/linux-loong64" "0.23.1" + "@esbuild/linux-mips64el" "0.23.1" + "@esbuild/linux-ppc64" "0.23.1" + "@esbuild/linux-riscv64" "0.23.1" + "@esbuild/linux-s390x" "0.23.1" + "@esbuild/linux-x64" "0.23.1" + "@esbuild/netbsd-x64" "0.23.1" + "@esbuild/openbsd-arm64" "0.23.1" + "@esbuild/openbsd-x64" "0.23.1" + "@esbuild/sunos-x64" "0.23.1" + "@esbuild/win32-arm64" "0.23.1" + "@esbuild/win32-ia32" "0.23.1" + "@esbuild/win32-x64" "0.23.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -13299,6 +13479,21 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -13872,7 +14067,7 @@ fsevents@2.3.2, fsevents@^2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fsevents@~2.3.2: +fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -14036,6 +14231,11 @@ get-stream@^6.0.0, get-stream@^6.0.1: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -14044,6 +14244,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.7.5: + version "4.8.1" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz#8995eb391ae6e1638d251118c7b56de7eb425471" + integrity sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg== + dependencies: + resolve-pkg-maps "^1.0.0" + get-uri@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.2.tgz#e019521646f4a8ff6d291fbaea2c46da204bb75b" @@ -14061,6 +14268,20 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +giget@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.2.3.tgz#ef6845d1140e89adad595f7f3bb60aa31c672cb6" + integrity sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + defu "^6.1.4" + node-fetch-native "^1.6.3" + nypm "^0.3.8" + ohash "^1.1.3" + pathe "^1.1.2" + tar "^6.2.0" + git-diff@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/git-diff/-/git-diff-2.0.6.tgz#4a8ece670d64d1f9f4e68191ad8b1013900f6c1e" @@ -14873,6 +15094,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + humanize-duration@^3.32.0: version "3.32.0" resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-3.32.0.tgz#b25f64ef55d723b049b197b6b4aa3c96c202b6c9" @@ -15019,11 +15245,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indent-string@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-5.0.0.tgz#4fd2980fccaf8622d14c64d694f4cf33c81951a5" - integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== - infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -15052,11 +15273,6 @@ ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ini@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - init-package-json@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-3.0.2.tgz#f5bc9bac93f2bdc005778bc2271be642fecfcd69" @@ -15495,6 +15711,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -16083,6 +16304,11 @@ jiti@^1.17.1, jiti@^1.18.2: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.1.tgz#fa99e4b76a23053e0e7cde098efe1704a14c16f1" integrity sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg== +jiti@^1.21.6: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + join-component@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/join-component/-/join-component-1.1.0.tgz#b8417b750661a392bee2c2537c68b2a9d4977cd5" @@ -16510,10 +16736,25 @@ kysely-codegen@^0.15.0: micromatch "^4.0.5" minimist "^1.2.8" -kysely@^0.27.3: - version "0.27.3" - resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.27.3.tgz#6cc6c757040500b43c4ac596cdbb12be400ee276" - integrity sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA== +kysely-ctl@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/kysely-ctl/-/kysely-ctl-0.9.0.tgz#13a26defbd8cf9427c632df017d03802a380bf9c" + integrity sha512-Ek4u/4vXV1nATw/RFXMuG6g76nXcD2f5RSMX/n2lbYDh1sJ53wp7QVYbxuLJwEmfHtLXlQFpDe5xPV2URxs+wg== + dependencies: + c12 "^1.8.0" + citty "^0.1.4" + consola "^3.2.0" + nypm "^0.3.1" + ofetch "^1.3.4" + pathe "^1.1.2" + pkg-types "^1.1.0" + std-env "^3.4.0" + tsx "^4.9.0" + +kysely@^0.27.4: + version "0.27.4" + resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.27.4.tgz#96a0285467b380948b4de03b20d87e82d797449b" + integrity sha512-dyNKv2KRvYOQPLCAOCjjQuCk4YFd33BvGdf/o5bC7FiW+BB6snA81Zt+2wT9QDFzKqxKa5rrOmvlK/anehCcgA== launch-editor@^2.6.1: version "2.6.1" @@ -17115,7 +17356,7 @@ map-obj@^1.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= -map-obj@^4.0.0, map-obj@^4.1.0: +map-obj@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== @@ -17197,24 +17438,6 @@ memoizee@^0.4.14: next-tick "^1.1.0" timers-ext "^0.1.7" -meow@^10.1.2: - version "10.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-10.1.2.tgz#62951cb69afa69594142c8250806bc30a3912e4d" - integrity sha512-zbuAlN+V/sXlbGchNS9WTWjUzeamwMt/BApKCJi7B0QyZstZaMx0n4Unll/fg0njGtMdC9UP5SAscvOCLYdM+Q== - dependencies: - "@types/minimist" "^1.2.2" - camelcase-keys "^7.0.0" - decamelize "^5.0.0" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.2" - read-pkg-up "^8.0.0" - redent "^4.0.0" - trim-newlines "^4.0.2" - type-fest "^1.2.2" - yargs-parser "^20.2.9" - meow@^8.0.0: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -17292,12 +17515,17 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + mimic-response@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -min-indent@^1.0.0, min-indent@^1.0.1: +min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== @@ -17502,7 +17730,7 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" -mkdirp@1.0.4, mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.0: +mkdirp@1.0.4, mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -17514,6 +17742,16 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" +mlly@^1.7.1, mlly@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.2.tgz#21c0d04543207495b8d867eff0ac29fac9a023c0" + integrity sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA== + dependencies: + acorn "^8.12.1" + pathe "^1.1.2" + pkg-types "^1.2.0" + ufo "^1.5.4" + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -17524,11 +17762,6 @@ module-details-from-path@^1.0.3: resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== -moment@^2.29.3: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== - mongodb-uri@^0.9.7: version "0.9.7" resolved "https://registry.yarnpkg.com/mongodb-uri/-/mongodb-uri-0.9.7.tgz#0f771ad16f483ae65f4287969428e9fbc4aa6181" @@ -17637,13 +17870,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -nconf@indexzero/nconf#ce212b2f1dbf96cee001b5f621979c564638f0e7: - version "1.0.0-beta.0" - resolved "https://codeload.github.com/indexzero/nconf/tar.gz/ce212b2f1dbf96cee001b5f621979c564638f0e7" - dependencies: - ini "^2.0.0" - yargs "^17.0.0" - needle@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" @@ -17758,6 +17984,11 @@ node-fetch-h2@^2.3.0: dependencies: http2-client "^1.2.5" +node-fetch-native@^1.6.3, node-fetch-native@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.4.tgz#679fc8fd8111266d47d7e72c379f1bed9acff06e" + integrity sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ== + node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -17815,16 +18046,6 @@ node-loader@^2.0.0: dependencies: loader-utils "^2.0.0" -node-pg-migrate@^5.9.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/node-pg-migrate/-/node-pg-migrate-5.10.0.tgz#64e1e0782c129255104b6bc32cbb2c9293bd7b42" - integrity sha512-SSLLTYWYBKnlqZAikoouzIumeThoGZKrfzduWDnXDwtAgMnmPyIUpzgqBfHQkQJlSprVJMnF1n66xk7RkZlbPg== - dependencies: - "@types/pg" "^8.0.0" - decamelize "^5.0.0" - mkdirp "~1.0.0" - yargs "~16.2.0" - node-pre-gyp@^0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.17.0.tgz#5af3f7b4c3848b5ed00edc3d298ff836daae5f1d" @@ -17902,7 +18123,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-package-data@^3.0.0, normalize-package-data@^3.0.2: +normalize-package-data@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== @@ -18038,6 +18259,13 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== + dependencies: + path-key "^4.0.0" + npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -18138,6 +18366,18 @@ nx@15.6.3, "nx@>=15.4.2 < 16": yargs "^17.6.2" yargs-parser "21.1.1" +nypm@^0.3.1, nypm@^0.3.8: + version "0.3.12" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.3.12.tgz#37541bec0af3a37d3acd81d6662c6666e650b22e" + integrity sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + execa "^8.0.1" + pathe "^1.1.2" + pkg-types "^1.2.0" + ufo "^1.5.4" + oas-kit-common@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/oas-kit-common/-/oas-kit-common-1.0.8.tgz#6d8cacf6e9097967a4c7ea8bcbcbd77018e1f535" @@ -18306,11 +18546,25 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -obuf@^1.0.0, obuf@^1.1.2: +obuf@^1.0.0, obuf@^1.1.2, obuf@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +ofetch@^1.3.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.4.1.tgz#b6bf6b0d75ba616cef6519dd8b6385a8bae480ec" + integrity sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw== + dependencies: + destr "^2.0.3" + node-fetch-native "^1.6.4" + ufo "^1.5.4" + +ohash@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.4.tgz#ae8d83014ab81157d2c285abf7792e2995fadd72" + integrity sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g== + on-finished@2.4.1, on-finished@^2.3.0, on-finished@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -18337,6 +18591,13 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + open@^10.0.3: version "10.1.0" resolved "https://registry.yarnpkg.com/open/-/open-10.1.0.tgz#a7795e6e5d519abe4286d9937bb24b51122598e1" @@ -18788,6 +19049,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -18855,47 +19121,67 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== +perfect-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" + integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== + +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + pg-connection-string@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== +pg-connection-string@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.7.0.tgz#f1d3489e427c62ece022dba98d5262efcb168b37" + integrity sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA== + pg-int8@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== -pg-minify@1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/pg-minify/-/pg-minify-1.6.2.tgz#055acfe862cfca3ca0a529020846b0f308d68e70" - integrity sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg== +pg-numeric@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" + integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== pg-pool@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.2.tgz#ed1bed1fb8d79f1c6fd5fb1c99e990fbf9ddf178" integrity sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w== -pg-promise@^11.2.0: - version "11.2.0" - resolved "https://registry.yarnpkg.com/pg-promise/-/pg-promise-11.2.0.tgz#86990e8076401db08d0fa74372ddfcff5da43390" - integrity sha512-aAYW0yWvwS02VdIrzZApRaIrZL71ckCl0/biZPXFvueWGMXzvRbDf4G2l1yU+pA2fiYxu+hYZIFztCuloK1MDQ== - dependencies: - assert-options "0.8.0" - pg "8.9.0" - pg-minify "1.6.2" - spex "3.2.0" +pg-pool@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.7.0.tgz#d4d3c7ad640f8c6a2245adc369bafde4ebb8cbec" + integrity sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g== + +pg-protocol@*, pg-protocol@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.7.0.tgz#ec037c87c20515372692edac8b63cf4405448a93" + integrity sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ== -pg-protocol@*, pg-protocol@^1.6.0: +pg-protocol@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== -pg-types@^2.1.0, pg-types@^2.2.0: +pg-types@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== @@ -18906,7 +19192,33 @@ pg-types@^2.1.0, pg-types@^2.2.0: postgres-date "~1.0.4" postgres-interval "^1.1.0" -pg@8.9.0, pg@^8.5.1: +pg-types@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-4.0.2.tgz#399209a57c326f162461faa870145bb0f918b76d" + integrity sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng== + dependencies: + pg-int8 "1.0.1" + pg-numeric "1.0.2" + postgres-array "~3.0.1" + postgres-bytea "~3.0.0" + postgres-date "~2.1.0" + postgres-interval "^3.0.0" + postgres-range "^1.1.1" + +pg@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.13.0.tgz#e3d245342eb0158112553fcc1890a60720ae2a3d" + integrity sha512-34wkUTh3SxTClfoHB3pQ7bIMvw9dpFU1audQQeZG837fmHfHpr14n/AELVDoOYVDW2h5RDWU78tFjkD+erSBsw== + dependencies: + pg-connection-string "^2.7.0" + pg-pool "^3.7.0" + pg-protocol "^1.7.0" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pg@^8.5.1: version "8.9.0" resolved "https://registry.yarnpkg.com/pg/-/pg-8.9.0.tgz#73c5d77a854d36b0e185450dacb8b90c669e040b" integrity sha512-ZJM+qkEbtOHRuXjmvBtOgNOXOtLSbxiMiUVMgE4rV6Zwocy03RicCVvDXgx8l4Biwo8/qORUnEqn2fdQzV7KCg== @@ -19017,6 +19329,15 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-types@^1.1.0, pkg-types@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.2.1.tgz#6ac4e455a5bb4b9a6185c1c79abd544c901db2e5" + integrity sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw== + dependencies: + confbox "^0.1.8" + mlly "^1.7.2" + pathe "^1.1.2" + playwright-core@1.34.3: version "1.34.3" resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.34.3.tgz#bc906ea1b26bb66116ce329436ee59ba2e78fe9f" @@ -19223,16 +19544,33 @@ postgres-array@~2.0.0: resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== +postgres-array@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98" + integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog== + postgres-bytea@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= +postgres-bytea@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089" + integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw== + dependencies: + obuf "~1.1.2" + postgres-date@~1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== +postgres-date@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-2.1.0.tgz#b85d3c1fb6fb3c6c8db1e9942a13a3bf625189d0" + integrity sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA== + postgres-interval@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" @@ -19240,6 +19578,16 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +postgres-interval@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a" + integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw== + +postgres-range@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.4.tgz#a59c5f9520909bcec5e63e8cf913a92e4c952863" + integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w== + pprof-format@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/pprof-format/-/pprof-format-2.1.0.tgz#acc8d7773bcf4faf0a3d3df11bceefba7ac06664" @@ -19781,6 +20129,14 @@ raw-loader@^4.0.2: loader-utils "^2.0.0" schema-utils "^3.0.0" +rc9@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/rc9/-/rc9-2.1.2.tgz#6282ff638a50caa0a91a31d76af4a0b9cbd1080d" + integrity sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg== + dependencies: + defu "^6.1.4" + destr "^2.0.3" + rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -20100,15 +20456,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg-up@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-8.0.0.tgz#72f595b65e66110f43b052dd9af4de6b10534670" - integrity sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ== - dependencies: - find-up "^5.0.0" - read-pkg "^6.0.0" - type-fest "^1.0.1" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -20128,16 +20475,6 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -read-pkg@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-6.0.0.tgz#a67a7d6a1c2b0c3cd6aa2ea521f40c458a4a504c" - integrity sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^3.0.2" - parse-json "^5.2.0" - type-fest "^1.0.1" - read@1, read@^1.0.4, read@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" @@ -20233,14 +20570,6 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -redent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-4.0.0.tgz#0c0ba7caabb24257ab3bb7a4fd95dd1d5c5681f9" - integrity sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag== - dependencies: - indent-string "^5.0.0" - strip-indent "^4.0.0" - redis-errors@^1.0.0, redis-errors@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" @@ -20524,6 +20853,11 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -20563,24 +20897,6 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -rethinkdb-ts-migrate@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/rethinkdb-ts-migrate/-/rethinkdb-ts-migrate-0.3.6.tgz#6621295a984b0b0d0e16ac4b242786903063fd29" - integrity sha512-Q9yZVZ+6kiWXT2fykjKYNUD82ZH+jr/b+Ps969olWy4Pdu0W1kHlnW13g3DSL/QdNPDNZIDJury3Pw6hM5gc3w== - dependencies: - chalk "^4.1.0" - meow "^10.1.2" - moment "^2.29.3" - nconf indexzero/nconf#ce212b2f1dbf96cee001b5f621979c564638f0e7 - rethinkdb-ts "^2.4.5" - sucrase "^3.21.0" - tslib "^2.4.0" - -rethinkdb-ts@2.6.0, rethinkdb-ts@^2.4.5: - version "2.6.0" - resolved "https://registry.yarnpkg.com/rethinkdb-ts/-/rethinkdb-ts-2.6.0.tgz#25ad1561d58836761463718470310b4bf911f9eb" - integrity sha512-RKkTP/P1dNNK265qmNjBqiiWlawRw7+MNVoro9UJa8RPvdB9+MJwzWxz7rgTLrfJr77FuaRQMqzlRexx6ivfUQ== - retry-request@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-7.0.2.tgz#60bf48cfb424ec01b03fca6665dee91d06dd95f3" @@ -21150,6 +21466,11 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.1.tgz#96a61033896120ec9335d96851d902cc98f0ba2a" integrity sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw== +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + signedsource@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a" @@ -21428,11 +21749,6 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -spex@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spex/-/spex-3.2.0.tgz#fa4a21922407e112624977b445a6d634578a1127" - integrity sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg== - split2@^3.0.0: version "3.2.2" resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" @@ -21557,6 +21873,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +std-env@^3.4.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== + stream-events@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" @@ -21620,7 +21941,7 @@ string-similarity@^3.0.0: resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-3.0.0.tgz#07b0bc69fae200ad88ceef4983878d03793847c7" integrity sha512-7kS7LyTp56OqOI2BDWQNVnLX/rCxIQn+/5M0op1WV6P8Xx6TZNdajpuqQdiJ7Xx+p1C5CsWMvdiBp9ApMhxzEQ== -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -21638,15 +21959,6 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.0.tgz#5ab00980cfb29f43e736b113a120a73a0fb569d3" @@ -21718,7 +22030,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -21732,13 +22044,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -21766,6 +22071,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -21773,13 +22083,6 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" - integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== - dependencies: - min-indent "^1.0.1" - strip-json-comments@^2.0.0, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -21838,7 +22141,7 @@ stylis@4.0.13: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== -sucrase@^3.21.0, sucrase@^3.32.0: +sucrase@^3.32.0: version "3.32.0" resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== @@ -22023,7 +22326,7 @@ tar@^4.4.13: safe-buffer "^5.2.1" yallist "^3.1.1" -tar@^6.0.2: +tar@^6.0.2, tar@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== @@ -22369,11 +22672,6 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -trim-newlines@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.0.2.tgz#d6aaaf6a0df1b4b536d183879a6b939489808c7c" - integrity sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew== - trim@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" @@ -22544,6 +22842,16 @@ tslib@~2.5.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tsx@^4.9.0: + version "4.19.1" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.1.tgz#b7bffdf4b565813e4dea14b90872af279cd0090b" + integrity sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA== + dependencies: + esbuild "~0.23.0" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -22615,11 +22923,6 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-fest@^1.0.1, type-fest@^1.2.1, type-fest@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" - integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== - type-fest@^2.0.0: version "2.19.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" @@ -22683,6 +22986,11 @@ uc.micro@^1.0.1, uc.micro@^1.0.5: resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== +ufo@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754" + integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ== + uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" @@ -23586,7 +23894,7 @@ workbox-window@6.5.4: "@types/trusted-types" "^2.0.2" workbox-core "6.5.4" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -23604,15 +23912,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -23823,7 +24122,7 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: +yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== @@ -23845,7 +24144,7 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.2.0, yargs@~16.2.0: +yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==