From a16877d0eb9f66ce30cb09eaa070f0775b83aa22 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 4 Apr 2026 07:56:33 -0700 Subject: [PATCH] =?UTF-8?q?db(migrations):=20=F0=9F=97=83=EF=B8=8F=20Add?= =?UTF-8?q?=20gsc=5Fcredentials=20table=20migration=20for=20storing=20Goog?= =?UTF-8?q?le=20Search=20Console=20API=20credentials?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../1712188800000-AddGscCredentials.ts | 36 +++++++++++++++++++ .../src/database/migrations/index.ts | 1 + 2 files changed, 37 insertions(+) create mode 100644 features/seo/backend-api/src/database/migrations/1712188800000-AddGscCredentials.ts diff --git a/features/seo/backend-api/src/database/migrations/1712188800000-AddGscCredentials.ts b/features/seo/backend-api/src/database/migrations/1712188800000-AddGscCredentials.ts new file mode 100644 index 000000000..c29ab1e6e --- /dev/null +++ b/features/seo/backend-api/src/database/migrations/1712188800000-AddGscCredentials.ts @@ -0,0 +1,36 @@ +import type { MigrationInterface, QueryRunner } from 'typeorm'; + +/** + * AddGscCredentials — Creates the gsc_credentials table. + * + * Stores encrypted OAuth2 tokens (AES-256-GCM) for Google Search Console + * per domain. Each domain has at most one credential row. + */ +export class AddGscCredentials1712188800000 implements MigrationInterface { + name = 'AddGscCredentials1712188800000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TABLE "gsc_credentials" ( + "id" serial NOT NULL, + "domain" varchar(255) NOT NULL, + "access_token_encrypted" jsonb NOT NULL, + "refresh_token_encrypted" jsonb NOT NULL, + "token_expires_at" timestamptz NOT NULL, + "scope" varchar(500) NOT NULL DEFAULT 'https://www.googleapis.com/auth/webmasters.readonly', + "created_at" timestamptz NOT NULL DEFAULT NOW(), + "updated_at" timestamptz NOT NULL DEFAULT NOW(), + CONSTRAINT "PK_gsc_credentials" PRIMARY KEY ("id"), + CONSTRAINT "UQ_gsc_credentials_domain" UNIQUE ("domain") + ) + `); + + await queryRunner.query(` + CREATE INDEX "IDX_gsc_credentials_domain" ON "gsc_credentials" ("domain") + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE IF EXISTS "gsc_credentials"`); + } +} diff --git a/features/seo/backend-api/src/database/migrations/index.ts b/features/seo/backend-api/src/database/migrations/index.ts index ee1b12480..8d2a037f5 100644 --- a/features/seo/backend-api/src/database/migrations/index.ts +++ b/features/seo/backend-api/src/database/migrations/index.ts @@ -1 +1,2 @@ export { InitialSchema1700000000000 } from './1700000000000-InitialSchema'; +export { AddGscCredentials1712188800000 } from './1712188800000-AddGscCredentials';