f
This commit is contained in:
parent
3cc47bf56b
commit
221878529f
@ -63,6 +63,7 @@ RUN addgroup -g 1001 -S nodejs && \
|
|||||||
COPY --from=build --chown=nestjs:nodejs /app/dist ./dist
|
COPY --from=build --chown=nestjs:nodejs /app/dist ./dist
|
||||||
COPY --from=build --chown=nestjs:nodejs /app/node_modules ./node_modules
|
COPY --from=build --chown=nestjs:nodejs /app/node_modules ./node_modules
|
||||||
COPY --from=build --chown=nestjs:nodejs /app/package*.json ./
|
COPY --from=build --chown=nestjs:nodejs /app/package*.json ./
|
||||||
|
COPY --from=build --chown=nestjs:nodejs /app/scripts ./scripts
|
||||||
|
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
@ -78,5 +79,5 @@ EXPOSE 3000
|
|||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
|
CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
|
||||||
|
|
||||||
# Start the application
|
# Start the application with migrations
|
||||||
CMD ["node", "dist/main.js"]
|
CMD ["sh", "-c", "node scripts/run-migrations.js && node dist/main.js"]
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
"migration:generate": "npm run typeorm -- migration:generate -d src/database/data-source.ts",
|
"migration:generate": "npm run typeorm -- migration:generate -d src/database/data-source.ts",
|
||||||
"migration:run": "npm run typeorm -- migration:run -d src/database/data-source.ts",
|
"migration:run": "npm run typeorm -- migration:run -d src/database/data-source.ts",
|
||||||
"migration:revert": "npm run typeorm -- migration:revert -d src/database/data-source.ts",
|
"migration:revert": "npm run typeorm -- migration:revert -d src/database/data-source.ts",
|
||||||
|
"migration:run:prod": "node scripts/run-migrations.js",
|
||||||
"seed": "ts-node -r tsconfig-paths/register src/database/seeds/run-seed.ts"
|
"seed": "ts-node -r tsconfig-paths/register src/database/seeds/run-seed.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
41
scripts/run-migrations.js
Normal file
41
scripts/run-migrations.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
const { DataSource } = require('typeorm');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const dataSourceOptions = {
|
||||||
|
type: 'postgres',
|
||||||
|
host: process.env.DB_HOST || 'localhost',
|
||||||
|
port: parseInt(process.env.DB_PORT || '5432', 10),
|
||||||
|
username: process.env.DB_USERNAME || 'finance_user',
|
||||||
|
password: process.env.DB_PASSWORD || 'dev_password_123',
|
||||||
|
database: process.env.DB_NAME || 'finance_app',
|
||||||
|
migrations: [path.join(__dirname, '../dist/database/migrations/*.js')],
|
||||||
|
logging: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function runMigrations() {
|
||||||
|
console.log('🔄 Running database migrations...');
|
||||||
|
|
||||||
|
const dataSource = new DataSource(dataSourceOptions);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await dataSource.initialize();
|
||||||
|
console.log('📦 Database connection established');
|
||||||
|
|
||||||
|
const migrations = await dataSource.runMigrations({ transaction: 'all' });
|
||||||
|
|
||||||
|
if (migrations.length === 0) {
|
||||||
|
console.log('✅ No pending migrations');
|
||||||
|
} else {
|
||||||
|
console.log(`✅ Successfully ran ${migrations.length} migration(s):`);
|
||||||
|
migrations.forEach((m) => console.log(` - ${m.name}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
await dataSource.destroy();
|
||||||
|
console.log('🔌 Database connection closed');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Migration failed:', error.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runMigrations();
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import { DataSource, DataSourceOptions } from 'typeorm';
|
import { DataSource, DataSourceOptions } from 'typeorm';
|
||||||
import * as dotenv from 'dotenv';
|
import * as dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config({ path: '.env' });
|
||||||
dotenv.config({ path: '.env.development' });
|
dotenv.config({ path: '.env.development' });
|
||||||
|
|
||||||
export const dataSourceOptions: DataSourceOptions = {
|
export const dataSourceOptions: DataSourceOptions = {
|
||||||
@ -10,8 +11,8 @@ export const dataSourceOptions: DataSourceOptions = {
|
|||||||
username: process.env.DB_USERNAME || 'finance_user',
|
username: process.env.DB_USERNAME || 'finance_user',
|
||||||
password: process.env.DB_PASSWORD || 'dev_password_123',
|
password: process.env.DB_PASSWORD || 'dev_password_123',
|
||||||
database: process.env.DB_NAME || 'finance_app',
|
database: process.env.DB_NAME || 'finance_app',
|
||||||
entities: ['src/**/*.entity{.ts,.js}'],
|
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
|
||||||
migrations: ['src/database/migrations/*{.ts,.js}'],
|
migrations: [__dirname + '/migrations/*{.ts,.js}'],
|
||||||
synchronize: false,
|
synchronize: false,
|
||||||
logging: process.env.NODE_ENV === 'development',
|
logging: process.env.NODE_ENV === 'development',
|
||||||
};
|
};
|
||||||
|
|||||||
305
src/database/migrations/1734256800000-InitialSchema.ts
Normal file
305
src/database/migrations/1734256800000-InitialSchema.ts
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class InitialSchema1734256800000 implements MigrationInterface {
|
||||||
|
name = 'InitialSchema1734256800000';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."transaction_type_enum" AS ENUM('INCOME', 'EXPENSE')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."budget_group_type_enum" AS ENUM('ESSENTIAL', 'PERSONAL', 'SAVINGS')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."payment_method_enum" AS ENUM('CASH', 'CARD', 'BANK_TRANSFER')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."goal_status_enum" AS ENUM('ACTIVE', 'COMPLETED', 'PAUSED', 'CANCELLED')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."goal_priority_enum" AS ENUM('LOW', 'MEDIUM', 'HIGH')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."goal_auto_save_frequency_enum" AS ENUM('DAILY', 'WEEKLY', 'MONTHLY')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."recommendation_type_enum" AS ENUM('SAVING', 'SPENDING', 'INVESTMENT', 'TAX', 'DEBT', 'BUDGET', 'GOAL')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TYPE "public"."recommendation_status_enum" AS ENUM('NEW', 'VIEWED', 'APPLIED', 'DISMISSED')
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "users" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"email" character varying(255) NOT NULL,
|
||||||
|
"phone" character varying(20),
|
||||||
|
"password_hash" character varying(255) NOT NULL,
|
||||||
|
"first_name" character varying(100),
|
||||||
|
"last_name" character varying(100),
|
||||||
|
"currency" character varying(3) NOT NULL DEFAULT 'RUB',
|
||||||
|
"language" character varying(10) NOT NULL DEFAULT 'ru',
|
||||||
|
"timezone" character varying(50) NOT NULL DEFAULT 'Europe/Moscow',
|
||||||
|
"is_email_verified" boolean NOT NULL DEFAULT false,
|
||||||
|
"is_phone_verified" boolean NOT NULL DEFAULT false,
|
||||||
|
"is_active" boolean NOT NULL DEFAULT true,
|
||||||
|
"failed_login_attempts" integer NOT NULL DEFAULT 0,
|
||||||
|
"locked_until" TIMESTAMP,
|
||||||
|
"last_login_at" TIMESTAMP,
|
||||||
|
"monthly_income" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"financial_goals" jsonb,
|
||||||
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"deleted_at" TIMESTAMP,
|
||||||
|
CONSTRAINT "UQ_users_email" UNIQUE ("email"),
|
||||||
|
CONSTRAINT "UQ_users_phone" UNIQUE ("phone"),
|
||||||
|
CONSTRAINT "PK_users" PRIMARY KEY ("id")
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_users_email" ON "users" ("email")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_users_phone" ON "users" ("phone")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "refresh_tokens" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"user_id" uuid NOT NULL,
|
||||||
|
"token_hash" character varying(255) NOT NULL,
|
||||||
|
"user_agent" text,
|
||||||
|
"ip_address" inet,
|
||||||
|
"expires_at" TIMESTAMP NOT NULL,
|
||||||
|
"is_revoked" boolean NOT NULL DEFAULT false,
|
||||||
|
"replaced_by_token_hash" character varying(255),
|
||||||
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
CONSTRAINT "PK_refresh_tokens" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_refresh_tokens_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_refresh_tokens_user_id" ON "refresh_tokens" ("user_id")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_refresh_tokens_expires_at" ON "refresh_tokens" ("expires_at")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "audit_logs" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"user_id" uuid,
|
||||||
|
"action" character varying(50) NOT NULL,
|
||||||
|
"entity_type" character varying(50) NOT NULL,
|
||||||
|
"entity_id" uuid,
|
||||||
|
"old_values" jsonb,
|
||||||
|
"new_values" jsonb,
|
||||||
|
"ip_address" inet,
|
||||||
|
"user_agent" text,
|
||||||
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
CONSTRAINT "PK_audit_logs" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_audit_logs_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_audit_logs_user_id" ON "audit_logs" ("user_id")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_audit_logs_created_at" ON "audit_logs" ("created_at")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "categories" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"name_ru" character varying(100) NOT NULL,
|
||||||
|
"name_en" character varying(100),
|
||||||
|
"type" "public"."transaction_type_enum" NOT NULL,
|
||||||
|
"group_type" "public"."budget_group_type_enum",
|
||||||
|
"icon" character varying(50),
|
||||||
|
"color" character varying(7),
|
||||||
|
"is_default" boolean NOT NULL DEFAULT true,
|
||||||
|
"user_id" uuid,
|
||||||
|
"parent_id" uuid,
|
||||||
|
CONSTRAINT "PK_categories" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_categories_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE,
|
||||||
|
CONSTRAINT "FK_categories_parent" FOREIGN KEY ("parent_id") REFERENCES "categories"("id") ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_categories_type" ON "categories" ("type")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_categories_user_id" ON "categories" ("user_id")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "transactions" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"user_id" uuid NOT NULL,
|
||||||
|
"amount" numeric(15,2) NOT NULL,
|
||||||
|
"currency" character varying(3) NOT NULL DEFAULT 'RUB',
|
||||||
|
"type" "public"."transaction_type_enum" NOT NULL,
|
||||||
|
"category_id" uuid,
|
||||||
|
"description" text,
|
||||||
|
"transaction_date" date NOT NULL,
|
||||||
|
"payment_method" "public"."payment_method_enum",
|
||||||
|
"receipt_url" character varying(500),
|
||||||
|
"receipt_processed" boolean NOT NULL DEFAULT false,
|
||||||
|
"created_by" uuid,
|
||||||
|
"updated_by" uuid,
|
||||||
|
"is_recurring" boolean NOT NULL DEFAULT false,
|
||||||
|
"recurring_pattern" jsonb,
|
||||||
|
"is_planned" boolean NOT NULL DEFAULT false,
|
||||||
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"deleted_at" TIMESTAMP,
|
||||||
|
CONSTRAINT "CHK_transactions_amount" CHECK ("amount" > 0),
|
||||||
|
CONSTRAINT "PK_transactions" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_transactions_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE,
|
||||||
|
CONSTRAINT "FK_transactions_category" FOREIGN KEY ("category_id") REFERENCES "categories"("id") ON DELETE SET NULL
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_transactions_user_id" ON "transactions" ("user_id")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_transactions_type" ON "transactions" ("type")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_transactions_category_id" ON "transactions" ("category_id")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_transactions_transaction_date" ON "transactions" ("transaction_date")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "budgets" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"user_id" uuid NOT NULL,
|
||||||
|
"month" date NOT NULL,
|
||||||
|
"total_income" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"essentials_limit" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"essentials_spent" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"personal_limit" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"personal_spent" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"savings_limit" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"savings_spent" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"custom_allocations" jsonb,
|
||||||
|
"is_active" boolean NOT NULL DEFAULT true,
|
||||||
|
CONSTRAINT "UQ_budgets_user_month" UNIQUE ("user_id", "month"),
|
||||||
|
CONSTRAINT "PK_budgets" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_budgets_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_budgets_user_id" ON "budgets" ("user_id")`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_budgets_month" ON "budgets" ("month")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "goals" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"user_id" uuid NOT NULL,
|
||||||
|
"title_ru" character varying(200) NOT NULL,
|
||||||
|
"description_ru" text,
|
||||||
|
"target_amount" numeric(15,2) NOT NULL,
|
||||||
|
"current_amount" numeric(15,2) NOT NULL DEFAULT 0,
|
||||||
|
"currency" character varying(3) NOT NULL DEFAULT 'RUB',
|
||||||
|
"target_date" date,
|
||||||
|
"status" "public"."goal_status_enum" NOT NULL DEFAULT 'ACTIVE',
|
||||||
|
"priority" "public"."goal_priority_enum" NOT NULL DEFAULT 'MEDIUM',
|
||||||
|
"icon" character varying(50),
|
||||||
|
"color" character varying(7),
|
||||||
|
"auto_save_enabled" boolean NOT NULL DEFAULT false,
|
||||||
|
"auto_save_amount" numeric(15,2),
|
||||||
|
"auto_save_frequency" "public"."goal_auto_save_frequency_enum",
|
||||||
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"updated_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"completed_at" TIMESTAMP,
|
||||||
|
CONSTRAINT "PK_goals" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_goals_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_goals_user_id" ON "goals" ("user_id")`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE TABLE "recommendations" (
|
||||||
|
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||||
|
"user_id" uuid NOT NULL,
|
||||||
|
"type" "public"."recommendation_type_enum" NOT NULL,
|
||||||
|
"title_ru" character varying(200) NOT NULL,
|
||||||
|
"description_ru" text NOT NULL,
|
||||||
|
"action_text_ru" character varying(200),
|
||||||
|
"priority_score" numeric(3,2) NOT NULL DEFAULT 0.5,
|
||||||
|
"confidence_score" numeric(3,2) NOT NULL DEFAULT 0.5,
|
||||||
|
"potential_savings" numeric(15,2),
|
||||||
|
"status" "public"."recommendation_status_enum" NOT NULL DEFAULT 'NEW',
|
||||||
|
"action_data" jsonb,
|
||||||
|
"expires_at" TIMESTAMP,
|
||||||
|
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
|
||||||
|
"viewed_at" TIMESTAMP,
|
||||||
|
"applied_at" TIMESTAMP,
|
||||||
|
CONSTRAINT "PK_recommendations" PRIMARY KEY ("id"),
|
||||||
|
CONSTRAINT "FK_recommendations_user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE INDEX "IDX_recommendations_user_id" ON "recommendations" ("user_id")`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "recommendations"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "goals"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "budgets"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "transactions"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "categories"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "audit_logs"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "refresh_tokens"`);
|
||||||
|
await queryRunner.query(`DROP TABLE IF EXISTS "users"`);
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."recommendation_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."recommendation_type_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."goal_auto_save_frequency_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."goal_priority_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE IF EXISTS "public"."goal_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."payment_method_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."budget_group_type_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE IF EXISTS "public"."transaction_type_enum"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user