Initial commit - Horux Despachos NL
This commit is contained in:
@@ -0,0 +1,634 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Plan" AS ENUM ('starter', 'business', 'business_ia', 'custom', 'enterprise');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PlatformRole" AS ENUM ('platform_admin', 'platform_ti', 'platform_support', 'platform_sales', 'platform_finance');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SatSyncType" AS ENUM ('initial', 'daily', 'incremental');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SatSyncStatus" AS ENUM ('pending', 'running', 'completed', 'failed');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CfdiSyncType" AS ENUM ('emitidos', 'recibidos');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "tenants" (
|
||||
"id" TEXT NOT NULL,
|
||||
"nombre" TEXT NOT NULL,
|
||||
"rfc" TEXT NOT NULL,
|
||||
"plan" "Plan" NOT NULL DEFAULT 'starter',
|
||||
"database_name" TEXT NOT NULL,
|
||||
"cfdi_limit" INTEGER NOT NULL DEFAULT 100,
|
||||
"users_limit" INTEGER NOT NULL DEFAULT 1,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expires_at" TIMESTAMP(3),
|
||||
"trial_ends_at" TIMESTAMP(3),
|
||||
"facturapi_org_id" TEXT,
|
||||
"codigo_postal" VARCHAR(5),
|
||||
"calle" VARCHAR(255),
|
||||
"num_exterior" VARCHAR(20),
|
||||
"num_interior" VARCHAR(20),
|
||||
"colonia" VARCHAR(255),
|
||||
"ciudad" VARCHAR(100),
|
||||
"municipio" VARCHAR(100),
|
||||
"estado" VARCHAR(100),
|
||||
"telefono" VARCHAR(20),
|
||||
|
||||
CONSTRAINT "tenants_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "users" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"password_hash" TEXT NOT NULL,
|
||||
"nombre" TEXT NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"last_login" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"token_version" INTEGER NOT NULL DEFAULT 0,
|
||||
"last_tenant_id" TEXT,
|
||||
|
||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "tenant_memberships" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"rol_id" INTEGER NOT NULL,
|
||||
"is_owner" BOOLEAN NOT NULL DEFAULT false,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"joined_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "tenant_memberships_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "roles" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"nombre" VARCHAR(20) NOT NULL,
|
||||
"descripcion" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "roles_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "refresh_tokens" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "refresh_tokens_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "password_reset_tokens" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"used_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "password_reset_tokens_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "regimenes" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(3) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
"tipo_persona" VARCHAR(20) NOT NULL,
|
||||
"activo" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "regimenes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "tenant_regimenes_ignorados" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"regimen_id" INTEGER NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "tenant_regimenes_ignorados_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "tenant_regimenes_activos" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"regimen_id" INTEGER NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "tenant_regimenes_activos_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "eventos_fiscales_catalogo" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"titulo" TEXT NOT NULL,
|
||||
"descripcion" TEXT,
|
||||
"tipo" VARCHAR(20) NOT NULL,
|
||||
"dia_base" INTEGER NOT NULL,
|
||||
"mes_relativo" INTEGER NOT NULL DEFAULT 1,
|
||||
"mes_fijo" INTEGER,
|
||||
"recurrencia" VARCHAR(20) NOT NULL DEFAULT 'mensual',
|
||||
"usa_extension_rfc" BOOLEAN NOT NULL DEFAULT false,
|
||||
"regimenes" TEXT NOT NULL DEFAULT 'todos',
|
||||
"condicion" VARCHAR(50),
|
||||
"activo" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "eventos_fiscales_catalogo_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "lista_negra" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"rfc" VARCHAR(13) NOT NULL,
|
||||
"nombre" TEXT NOT NULL,
|
||||
"situacion" VARCHAR(30) NOT NULL,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "lista_negra_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "dias_inhabiles" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"fecha" DATE NOT NULL,
|
||||
"nombre" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "dias_inhabiles_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "isr_resico_tasas" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"anio" INTEGER NOT NULL,
|
||||
"monto_maximo" DECIMAL(18,2) NOT NULL,
|
||||
"porcentaje" DECIMAL(5,2) NOT NULL,
|
||||
|
||||
CONSTRAINT "isr_resico_tasas_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "isr_tarifas" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"anio" INTEGER NOT NULL,
|
||||
"limite_inferior" DECIMAL(18,2) NOT NULL,
|
||||
"limite_superior" DECIMAL(18,2),
|
||||
"cuota_fija" DECIMAL(18,2) NOT NULL,
|
||||
"porcentaje_excedente" DECIMAL(5,2) NOT NULL,
|
||||
|
||||
CONSTRAINT "isr_tarifas_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "coeficiente_utilidad" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"anio" INTEGER NOT NULL,
|
||||
"coeficiente" DECIMAL(10,4) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "coeficiente_utilidad_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "fiel_credentials" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"rfc" VARCHAR(13) NOT NULL,
|
||||
"cer_data" BYTEA NOT NULL,
|
||||
"key_data" BYTEA NOT NULL,
|
||||
"key_password_encrypted" BYTEA NOT NULL,
|
||||
"cer_iv" BYTEA NOT NULL,
|
||||
"cer_tag" BYTEA NOT NULL,
|
||||
"key_iv" BYTEA NOT NULL,
|
||||
"key_tag" BYTEA NOT NULL,
|
||||
"password_iv" BYTEA NOT NULL,
|
||||
"password_tag" BYTEA NOT NULL,
|
||||
"serial_number" VARCHAR(50),
|
||||
"valid_from" TIMESTAMP(3) NOT NULL,
|
||||
"valid_until" TIMESTAMP(3) NOT NULL,
|
||||
"is_active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "fiel_credentials_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "subscriptions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"plan" "Plan" NOT NULL,
|
||||
"mp_preapproval_id" TEXT,
|
||||
"status" TEXT NOT NULL DEFAULT 'pending',
|
||||
"amount" DECIMAL(10,2) NOT NULL,
|
||||
"frequency" TEXT NOT NULL DEFAULT 'monthly',
|
||||
"current_period_start" TIMESTAMP(3),
|
||||
"current_period_end" TIMESTAMP(3),
|
||||
"pending_plan" "Plan",
|
||||
"pending_frequency" TEXT,
|
||||
"pending_effective_at" TIMESTAMP(3),
|
||||
"upgrade_preference_id" TEXT,
|
||||
"upgrade_target_plan" "Plan",
|
||||
"upgrade_target_amount" DECIMAL(10,2),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "subscriptions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_platform_roles" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"role" "PlatformRole" NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"created_by" TEXT,
|
||||
|
||||
CONSTRAINT "user_platform_roles_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "audit_log" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT,
|
||||
"tenant_id" TEXT,
|
||||
"action" VARCHAR(64) NOT NULL,
|
||||
"entity_type" VARCHAR(32),
|
||||
"entity_id" TEXT,
|
||||
"metadata" JSONB,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "audit_log_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "trial_usages" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"rfc" VARCHAR(13) NOT NULL,
|
||||
"tenant_id" TEXT,
|
||||
"started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "trial_usages_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "plan_prices" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"plan" "Plan" NOT NULL,
|
||||
"frequency" TEXT NOT NULL,
|
||||
"amount" DECIMAL(10,2) NOT NULL,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "plan_prices_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "payments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"subscription_id" TEXT,
|
||||
"mp_payment_id" TEXT,
|
||||
"amount" DECIMAL(10,2) NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'pending',
|
||||
"payment_method" TEXT,
|
||||
"paid_at" TIMESTAMP(3),
|
||||
"facturapi_invoice_id" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "payments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "sat_sync_jobs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"type" "SatSyncType" NOT NULL,
|
||||
"status" "SatSyncStatus" NOT NULL DEFAULT 'pending',
|
||||
"date_from" DATE NOT NULL,
|
||||
"date_to" DATE NOT NULL,
|
||||
"cfdi_type" "CfdiSyncType",
|
||||
"sat_request_id" VARCHAR(50),
|
||||
"sat_package_ids" TEXT[],
|
||||
"cfdis_found" INTEGER NOT NULL DEFAULT 0,
|
||||
"cfdis_downloaded" INTEGER NOT NULL DEFAULT 0,
|
||||
"cfdis_inserted" INTEGER NOT NULL DEFAULT 0,
|
||||
"cfdis_updated" INTEGER NOT NULL DEFAULT 0,
|
||||
"progress_percent" INTEGER NOT NULL DEFAULT 0,
|
||||
"error_message" TEXT,
|
||||
"started_at" TIMESTAMP(3),
|
||||
"completed_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"retry_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"next_retry_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "sat_sync_jobs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_forma_pago" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(2) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_forma_pago_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_metodo_pago" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(3) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_metodo_pago_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_uso_cfdi" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(4) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
"persona_fisica" BOOLEAN NOT NULL DEFAULT true,
|
||||
"persona_moral" BOOLEAN NOT NULL DEFAULT true,
|
||||
|
||||
CONSTRAINT "cat_uso_cfdi_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_moneda" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(3) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
"decimales" INTEGER NOT NULL DEFAULT 2,
|
||||
|
||||
CONSTRAINT "cat_moneda_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_clave_unidad" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(10) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_clave_unidad_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_clave_prod_serv" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(8) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_clave_prod_serv_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_objeto_imp" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(2) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_objeto_imp_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_tipo_relacion" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(2) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_tipo_relacion_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "cat_exportacion" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"clave" VARCHAR(2) NOT NULL,
|
||||
"descripcion" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "cat_exportacion_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "timbre_suscripciones" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"tipo" VARCHAR(10) NOT NULL,
|
||||
"timbres_limite" INTEGER NOT NULL,
|
||||
"timbres_usados" INTEGER NOT NULL DEFAULT 0,
|
||||
"periodo_inicio" DATE NOT NULL,
|
||||
"periodo_fin" DATE NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "timbre_suscripciones_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tenants_rfc_key" ON "tenants"("rfc");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tenants_database_name_key" ON "tenants"("database_name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "tenant_memberships_user_id_active_idx" ON "tenant_memberships"("user_id", "active");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "tenant_memberships_tenant_id_active_idx" ON "tenant_memberships"("tenant_id", "active");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tenant_memberships_user_id_tenant_id_key" ON "tenant_memberships"("user_id", "tenant_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "roles_nombre_key" ON "roles"("nombre");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "refresh_tokens_token_key" ON "refresh_tokens"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "password_reset_tokens_token_key" ON "password_reset_tokens"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "password_reset_tokens_user_id_idx" ON "password_reset_tokens"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "password_reset_tokens_expires_at_idx" ON "password_reset_tokens"("expires_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "regimenes_clave_key" ON "regimenes"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tenant_regimenes_ignorados_tenant_id_regimen_id_key" ON "tenant_regimenes_ignorados"("tenant_id", "regimen_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tenant_regimenes_activos_tenant_id_regimen_id_key" ON "tenant_regimenes_activos"("tenant_id", "regimen_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "lista_negra_rfc_key" ON "lista_negra"("rfc");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "lista_negra_rfc_idx" ON "lista_negra"("rfc");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "dias_inhabiles_fecha_key" ON "dias_inhabiles"("fecha");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "isr_resico_tasas_anio_monto_maximo_key" ON "isr_resico_tasas"("anio", "monto_maximo");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "isr_tarifas_anio_limite_inferior_key" ON "isr_tarifas"("anio", "limite_inferior");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "coeficiente_utilidad_tenant_id_anio_key" ON "coeficiente_utilidad"("tenant_id", "anio");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "fiel_credentials_tenant_id_key" ON "fiel_credentials"("tenant_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "subscriptions_tenant_id_idx" ON "subscriptions"("tenant_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "subscriptions_status_idx" ON "subscriptions"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "subscriptions_pending_effective_at_idx" ON "subscriptions"("pending_effective_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "user_platform_roles_role_idx" ON "user_platform_roles"("role");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_platform_roles_user_id_role_key" ON "user_platform_roles"("user_id", "role");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_log_user_id_created_at_idx" ON "audit_log"("user_id", "created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_log_tenant_id_created_at_idx" ON "audit_log"("tenant_id", "created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_log_action_created_at_idx" ON "audit_log"("action", "created_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "audit_log_entity_type_entity_id_idx" ON "audit_log"("entity_type", "entity_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "trial_usages_rfc_key" ON "trial_usages"("rfc");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "plan_prices_plan_frequency_key" ON "plan_prices"("plan", "frequency");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "payments_tenant_id_idx" ON "payments"("tenant_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "payments_subscription_id_idx" ON "payments"("subscription_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "sat_sync_jobs_tenant_id_idx" ON "sat_sync_jobs"("tenant_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "sat_sync_jobs_status_idx" ON "sat_sync_jobs"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "sat_sync_jobs_status_next_retry_at_idx" ON "sat_sync_jobs"("status", "next_retry_at");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_forma_pago_clave_key" ON "cat_forma_pago"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_metodo_pago_clave_key" ON "cat_metodo_pago"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_uso_cfdi_clave_key" ON "cat_uso_cfdi"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_moneda_clave_key" ON "cat_moneda"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_clave_unidad_clave_key" ON "cat_clave_unidad"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_clave_prod_serv_clave_key" ON "cat_clave_prod_serv"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "cat_clave_prod_serv_descripcion_idx" ON "cat_clave_prod_serv"("descripcion");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_objeto_imp_clave_key" ON "cat_objeto_imp"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_tipo_relacion_clave_key" ON "cat_tipo_relacion"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "cat_exportacion_clave_key" ON "cat_exportacion"("clave");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "timbre_suscripciones_tenant_id_key" ON "timbre_suscripciones"("tenant_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_memberships" ADD CONSTRAINT "tenant_memberships_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_memberships" ADD CONSTRAINT "tenant_memberships_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_memberships" ADD CONSTRAINT "tenant_memberships_rol_id_fkey" FOREIGN KEY ("rol_id") REFERENCES "roles"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "password_reset_tokens" ADD CONSTRAINT "password_reset_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_regimenes_ignorados" ADD CONSTRAINT "tenant_regimenes_ignorados_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_regimenes_ignorados" ADD CONSTRAINT "tenant_regimenes_ignorados_regimen_id_fkey" FOREIGN KEY ("regimen_id") REFERENCES "regimenes"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_regimenes_activos" ADD CONSTRAINT "tenant_regimenes_activos_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "tenant_regimenes_activos" ADD CONSTRAINT "tenant_regimenes_activos_regimen_id_fkey" FOREIGN KEY ("regimen_id") REFERENCES "regimenes"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "coeficiente_utilidad" ADD CONSTRAINT "coeficiente_utilidad_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "fiel_credentials" ADD CONSTRAINT "fiel_credentials_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "user_platform_roles" ADD CONSTRAINT "user_platform_roles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "payments" ADD CONSTRAINT "payments_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "payments" ADD CONSTRAINT "payments_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "subscriptions"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "sat_sync_jobs" ADD CONSTRAINT "sat_sync_jobs_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "timbre_suscripciones" ADD CONSTRAINT "timbre_suscripciones_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PaymentKind" AS ENUM ('subscription', 'timbres_pack');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "payments" ADD COLUMN "kind" "PaymentKind" NOT NULL DEFAULT 'subscription';
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "timbre_paquetes_catalogo" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"cantidad" INTEGER NOT NULL,
|
||||
"precio" DECIMAL(10,2) NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "timbre_paquetes_catalogo_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "timbre_paquetes" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"payment_id" TEXT,
|
||||
"cantidad" INTEGER NOT NULL,
|
||||
"usados" INTEGER NOT NULL DEFAULT 0,
|
||||
"precio" DECIMAL(10,2) NOT NULL,
|
||||
"adquirido_en" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expira_en" TIMESTAMP(3) NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "timbre_paquetes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "timbre_paquetes_catalogo_cantidad_key" ON "timbre_paquetes_catalogo"("cantidad");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "timbre_paquetes_payment_id_key" ON "timbre_paquetes"("payment_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "timbre_paquetes_tenant_id_expira_en_idx" ON "timbre_paquetes"("tenant_id", "expira_en");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "timbre_paquetes" ADD CONSTRAINT "timbre_paquetes_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "timbre_paquetes" ADD CONSTRAINT "timbre_paquetes_payment_id_fkey" FOREIGN KEY ("payment_id") REFERENCES "payments"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,16 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "VerticalProfile" AS ENUM ('CONTABLE', 'JURIDICO', 'ARQUITECTURA');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "DbMode" AS ENUM ('BYO', 'MANAGED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "tenants" ADD COLUMN "connector_last_seen" TIMESTAMP(3),
|
||||
ADD COLUMN "connector_token_enc" TEXT,
|
||||
ADD COLUMN "connector_tunnel_hostname" TEXT,
|
||||
ADD COLUMN "connector_version" VARCHAR(20),
|
||||
ADD COLUMN "db_connection_enc" TEXT,
|
||||
ADD COLUMN "db_connection_iv" TEXT,
|
||||
ADD COLUMN "db_mode" "DbMode",
|
||||
ADD COLUMN "db_schema_version" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "vertical_profile" "VerticalProfile";
|
||||
@@ -0,0 +1,35 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "plan_catalogo" (
|
||||
"id" TEXT NOT NULL,
|
||||
"codename" VARCHAR(50) NOT NULL,
|
||||
"nombre" TEXT NOT NULL,
|
||||
"verticalProfile" "VerticalProfile" NOT NULL,
|
||||
"precio_base" DECIMAL(10,2) NOT NULL,
|
||||
"frecuencia" VARCHAR(10) NOT NULL,
|
||||
"limits" JSONB NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "plan_catalogo_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "plan_addon_catalogo" (
|
||||
"id" TEXT NOT NULL,
|
||||
"codename" VARCHAR(50) NOT NULL,
|
||||
"nombre" TEXT NOT NULL,
|
||||
"verticalProfile" "VerticalProfile",
|
||||
"precio" DECIMAL(10,2) NOT NULL,
|
||||
"frecuencia" VARCHAR(10) NOT NULL,
|
||||
"delta" JSONB NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "plan_addon_catalogo_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "plan_catalogo_codename_key" ON "plan_catalogo"("codename");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "plan_addon_catalogo_codename_key" ON "plan_addon_catalogo"("codename");
|
||||
@@ -0,0 +1,28 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "subscription_addons" (
|
||||
"id" TEXT NOT NULL,
|
||||
"subscription_id" TEXT NOT NULL,
|
||||
"plan_addon_catalogo_id" TEXT NOT NULL,
|
||||
"mp_preapproval_id" TEXT,
|
||||
"status" TEXT NOT NULL DEFAULT 'pending',
|
||||
"quantity" INTEGER NOT NULL DEFAULT 1,
|
||||
"amount" DECIMAL(10,2) NOT NULL,
|
||||
"current_period_start" TIMESTAMP(3),
|
||||
"current_period_end" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "subscription_addons_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "subscription_addons_subscription_id_idx" ON "subscription_addons"("subscription_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "subscription_addons_subscription_id_plan_addon_catalogo_id_key" ON "subscription_addons"("subscription_id", "plan_addon_catalogo_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "subscription_addons" ADD CONSTRAINT "subscription_addons_subscription_id_fkey" FOREIGN KEY ("subscription_id") REFERENCES "subscriptions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "subscription_addons" ADD CONSTRAINT "subscription_addons_plan_addon_catalogo_id_fkey" FOREIGN KEY ("plan_addon_catalogo_id") REFERENCES "plan_addon_catalogo"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,19 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "connector_heartbeats" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenant_id" TEXT NOT NULL,
|
||||
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"latency_ms" INTEGER NOT NULL,
|
||||
"version" VARCHAR(20) NOT NULL,
|
||||
"pg_version" VARCHAR(50),
|
||||
"status" VARCHAR(20) NOT NULL,
|
||||
"error_msg" TEXT,
|
||||
|
||||
CONSTRAINT "connector_heartbeats_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "connector_heartbeats_tenant_id_timestamp_idx" ON "connector_heartbeats"("tenant_id", "timestamp");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "connector_heartbeats" ADD CONSTRAINT "connector_heartbeats_tenant_id_fkey" FOREIGN KEY ("tenant_id") REFERENCES "tenants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "sat_sync_jobs" ADD COLUMN "contribuyente_id" TEXT;
|
||||
@@ -0,0 +1,10 @@
|
||||
-- AlterEnum
|
||||
-- This migration adds more than one value to an enum.
|
||||
-- With PostgreSQL versions 11 and earlier, this is not possible
|
||||
-- in a single migration. This can be worked around by creating
|
||||
-- multiple migrations, each migration adding only one value to
|
||||
-- the enum.
|
||||
|
||||
|
||||
ALTER TYPE "Plan" ADD VALUE 'business_control';
|
||||
ALTER TYPE "Plan" ADD VALUE 'business_cloud';
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Add-ons por contribuyente: permite que SubscriptionAddon se asocie a un
|
||||
-- contribuyente específico (ej. Lolita IA $250/mes activable por RFC) además
|
||||
-- de los add-ons a nivel tenant (modulos, +RFCs, +timbres) que tienen
|
||||
-- contribuyente_id = NULL.
|
||||
|
||||
ALTER TABLE "subscription_addons"
|
||||
ADD COLUMN "contribuyente_id" TEXT;
|
||||
|
||||
-- Eliminar el UNIQUE (subscription_id, plan_addon_catalogo_id). Ahora el
|
||||
-- mismo add-on (p. ej. lolita_ia_contribuyente) puede tener N filas por
|
||||
-- subscription, una por cada contribuyente que lo contrate.
|
||||
ALTER TABLE "subscription_addons"
|
||||
DROP CONSTRAINT IF EXISTS "subscription_addons_subscription_id_plan_addon_catalogo_id_key";
|
||||
|
||||
-- Índice por (subscription_id, contribuyente_id) para lookups rápidos
|
||||
-- "qué add-ons tiene este contribuyente"
|
||||
CREATE INDEX IF NOT EXISTS "subscription_addons_subscription_id_contribuyente_id_idx"
|
||||
ON "subscription_addons"("subscription_id", "contribuyente_id");
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterEnum
|
||||
ALTER TYPE "Plan" ADD VALUE 'mi_empresa';
|
||||
@@ -0,0 +1,18 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "despacho_plan_prices" (
|
||||
"plan" TEXT NOT NULL,
|
||||
"monthly" DECIMAL(10,2),
|
||||
"first_year" DECIMAL(10,2) NOT NULL,
|
||||
"renewal" DECIMAL(10,2) NOT NULL,
|
||||
"permite_monthly" BOOLEAN NOT NULL DEFAULT false,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "despacho_plan_prices_pkey" PRIMARY KEY ("plan")
|
||||
);
|
||||
|
||||
-- Seed inicial con valores actuales del catálogo `DESPACHO_PLAN_PRICES`.
|
||||
INSERT INTO "despacho_plan_prices" ("plan", "monthly", "first_year", "renewal", "permite_monthly", "updated_at") VALUES
|
||||
('mi_empresa', 580, 5800, 5800, true, NOW()),
|
||||
('mi_empresa_plus', 900, 9000, 9000, true, NOW()),
|
||||
('business_control', NULL, 25850, 25850, false, NOW()),
|
||||
('business_cloud', NULL, 43000, 43000, false, NOW());
|
||||
@@ -0,0 +1,19 @@
|
||||
-- AlterEnum
|
||||
BEGIN;
|
||||
CREATE TYPE "Plan_new" AS ENUM ('trial', 'custom', 'business_control', 'business_cloud', 'mi_empresa', 'mi_empresa_plus');
|
||||
ALTER TABLE "tenants" ALTER COLUMN "plan" DROP DEFAULT;
|
||||
ALTER TABLE "tenants" ALTER COLUMN "plan" TYPE "Plan_new" USING ("plan"::text::"Plan_new");
|
||||
ALTER TABLE "subscriptions" ALTER COLUMN "plan" TYPE "Plan_new" USING ("plan"::text::"Plan_new");
|
||||
ALTER TABLE "subscriptions" ALTER COLUMN "pending_plan" TYPE "Plan_new" USING ("pending_plan"::text::"Plan_new");
|
||||
ALTER TABLE "subscriptions" ALTER COLUMN "upgrade_target_plan" TYPE "Plan_new" USING ("upgrade_target_plan"::text::"Plan_new");
|
||||
ALTER TABLE "plan_prices" ALTER COLUMN "plan" TYPE "Plan_new" USING ("plan"::text::"Plan_new");
|
||||
ALTER TYPE "Plan" RENAME TO "Plan_old";
|
||||
ALTER TYPE "Plan_new" RENAME TO "Plan";
|
||||
DROP TYPE "Plan_old";
|
||||
ALTER TABLE "tenants" ALTER COLUMN "plan" SET DEFAULT 'trial';
|
||||
COMMIT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "tenants" DROP COLUMN "cfdi_limit",
|
||||
DROP COLUMN "users_limit",
|
||||
ALTER COLUMN "plan" SET DEFAULT 'trial';
|
||||
@@ -0,0 +1,55 @@
|
||||
-- Step 1: Add new columns as nullable (preserva las 4 filas existentes con sus precios)
|
||||
ALTER TABLE "despacho_plan_prices"
|
||||
ADD COLUMN "nombre" VARCHAR(50),
|
||||
ADD COLUMN "max_rfcs" INTEGER,
|
||||
ADD COLUMN "max_users" INTEGER,
|
||||
ADD COLUMN "db_mode" "DbMode",
|
||||
ADD COLUMN "timbres_incluidos_mes" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "permite_servidor_backup" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- Step 2: Backfill limits para las 4 filas existentes desde el catálogo TS
|
||||
UPDATE "despacho_plan_prices" SET
|
||||
"nombre" = 'Mi Empresa',
|
||||
"max_rfcs" = 1,
|
||||
"max_users" = 3,
|
||||
"timbres_incluidos_mes" = 50,
|
||||
"db_mode" = 'MANAGED'
|
||||
WHERE "plan" = 'mi_empresa';
|
||||
|
||||
UPDATE "despacho_plan_prices" SET
|
||||
"nombre" = 'Mi Empresa +',
|
||||
"max_rfcs" = 1,
|
||||
"max_users" = 3,
|
||||
"timbres_incluidos_mes" = 50,
|
||||
"db_mode" = 'MANAGED'
|
||||
WHERE "plan" = 'mi_empresa_plus';
|
||||
|
||||
UPDATE "despacho_plan_prices" SET
|
||||
"nombre" = 'Business Control',
|
||||
"max_rfcs" = 100,
|
||||
"max_users" = -1,
|
||||
"timbres_incluidos_mes" = 0,
|
||||
"db_mode" = 'BYO',
|
||||
"permite_servidor_backup" = true
|
||||
WHERE "plan" = 'business_control';
|
||||
|
||||
UPDATE "despacho_plan_prices" SET
|
||||
"nombre" = 'Enterprise',
|
||||
"max_rfcs" = 100,
|
||||
"max_users" = -1,
|
||||
"timbres_incluidos_mes" = 0,
|
||||
"db_mode" = 'BYO',
|
||||
"permite_servidor_backup" = true
|
||||
WHERE "plan" = 'business_cloud';
|
||||
|
||||
-- Step 3: Set NOT NULL después del backfill (las 4 filas ya están completas)
|
||||
ALTER TABLE "despacho_plan_prices"
|
||||
ALTER COLUMN "nombre" SET NOT NULL,
|
||||
ALTER COLUMN "max_rfcs" SET NOT NULL,
|
||||
ALTER COLUMN "max_users" SET NOT NULL,
|
||||
ALTER COLUMN "db_mode" SET NOT NULL;
|
||||
|
||||
-- Step 4: Hacer firstYear y renewal nullable para soportar trial y custom (sin precio fijo)
|
||||
ALTER TABLE "despacho_plan_prices"
|
||||
ALTER COLUMN "first_year" DROP NOT NULL,
|
||||
ALTER COLUMN "renewal" DROP NOT NULL;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- Drop tabla plan_catalogo (modelo huérfano nunca usado por código activo).
|
||||
-- Las 2 filas que tenía estaban desincronizadas con el catálogo TS y nunca
|
||||
-- se referenciaron desde código real. El catálogo despacho vive ahora en
|
||||
-- `despacho_plan_prices` (extendida con limits en migración 20260430195000).
|
||||
DROP TABLE "plan_catalogo";
|
||||
@@ -0,0 +1,10 @@
|
||||
-- Add column with default false (no-op para filas existentes)
|
||||
ALTER TABLE "despacho_plan_prices"
|
||||
ADD COLUMN "permite_sat_incremental" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- Backfill: planes que SÍ deben tener incremental (3 syncs/día adicionales).
|
||||
-- Mi Empresa + tiene API + Lolita IA y precio premium ($9k anual);
|
||||
-- Business Control y Enterprise son los planes despacho con escala alta.
|
||||
UPDATE "despacho_plan_prices"
|
||||
SET "permite_sat_incremental" = true
|
||||
WHERE "plan" IN ('mi_empresa_plus', 'business_control', 'business_cloud');
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Cache cifrada de la Live Secret Key de la organización Facturapi del tenant
|
||||
-- central (Horux 360 admin que emite facturas de subscripción a clientes).
|
||||
-- AES-256-GCM con derivación FIEL_ENCRYPTION_KEY — mismo patrón que FIEL.
|
||||
ALTER TABLE "tenants"
|
||||
ADD COLUMN "facturapi_org_key_enc" BYTEA,
|
||||
ADD COLUMN "facturapi_org_key_iv" BYTEA,
|
||||
ADD COLUMN "facturapi_org_key_tag" BYTEA;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- Drop tabla plan_prices (modelo legacy Horux 360 sin filas activas).
|
||||
-- Catálogo se reemplazó por DespachoPlanPrice (despacho_plan_prices) en
|
||||
-- migración 20260430195000_extend_despacho_plan_prices_with_limits.
|
||||
-- Sin callers activos en código (verificado vía typecheck post-cleanup).
|
||||
DROP TABLE "plan_prices";
|
||||
@@ -0,0 +1,5 @@
|
||||
-- Tracking de aviso pre-vencimiento por suscripción. Permite que el cron diario
|
||||
-- evite enviar dos emails del mismo bucket de días al mismo owner.
|
||||
ALTER TABLE "subscriptions"
|
||||
ADD COLUMN "last_reminder_day" INTEGER,
|
||||
ADD COLUMN "last_reminder_sent_at" TIMESTAMP(3);
|
||||
@@ -0,0 +1,8 @@
|
||||
-- Preferencias de auto-facturación de pagos de suscripción.
|
||||
-- factPreferencia: 'publico_general' o 'mis_datos' (default: mis_datos)
|
||||
-- factUsoCfdi: clave SAT del uso CFDI default (G03 = Gastos en general)
|
||||
-- factRegimenPreferido: clave del régimen fiscal a usar cuando hay multi-régimen
|
||||
ALTER TABLE "tenants"
|
||||
ADD COLUMN "fact_preferencia" VARCHAR(20) DEFAULT 'mis_datos' NOT NULL,
|
||||
ADD COLUMN "fact_uso_cfdi" VARCHAR(5) DEFAULT 'G03' NOT NULL,
|
||||
ADD COLUMN "fact_regimen_preferido" VARCHAR(3);
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Onboarding auto-dismiss: 4 logins ó pasos completados, lo que pase primero.
|
||||
ALTER TABLE "users"
|
||||
ADD COLUMN "login_count" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "onboarding_dismissed_at" TIMESTAMP(3);
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Mapa { kindKey: requestId } para reusar requests del SAT en reintentos.
|
||||
-- Hasta antes de este cambio, cada retry creaba nuevas solicitudes — agotaba
|
||||
-- la cuota del SAT y abandonaba requests anteriores. Ahora el retry consulta
|
||||
-- los requestIds previos antes de crear nuevos.
|
||||
ALTER TABLE "sat_sync_jobs"
|
||||
ADD COLUMN "sat_request_ids" JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Distingue extracciones tipo `initial` con rango personalizado (UI custom)
|
||||
-- de bootstrap inicial puro. Política de retry distinta:
|
||||
-- initial bootstrap → 3 retries a 6h, 12h, 24h
|
||||
-- initial custom → 2 retries a 6h, 12h
|
||||
ALTER TABLE "sat_sync_jobs"
|
||||
ADD COLUMN "is_custom_range" BOOLEAN NOT NULL DEFAULT false;
|
||||
3
apps/api/prisma/migrations/migration_lock.toml
Normal file
3
apps/api/prisma/migrations/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
Reference in New Issue
Block a user