feat: Add Google Analytics integration and fix anonymous tracking
- Add Google Analytics tracking (G-ZDZ26XYN2P) to frontend - Create comprehensive analytics utility with event tracking - Track URL submissions, analysis results, and user authentication - Add route tracking for SPA navigation - Fix CORS configuration to support both localhost and production - Fix home page tracking form to display results instead of auto-redirect - Add service management scripts for easier deployment - Update database migrations for enhanced analysis features Key Features: - Anonymous and authenticated user tracking - SSL/SEO/Security analysis event tracking - Error tracking for debugging - Page view tracking for SPA routes - Multi-origin CORS support for development and production
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Role" AS ENUM ('OWNER', 'ADMIN', 'MEMBER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CheckStatus" AS ENUM ('OK', 'ERROR', 'TIMEOUT', 'LOOP');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "RedirectType" AS ENUM ('HTTP_301', 'HTTP_302', 'HTTP_307', 'HTTP_308', 'META_REFRESH', 'JS', 'FINAL', 'OTHER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MixedContent" AS ENUM ('NONE', 'PRESENT', 'FINAL_TO_HTTP');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "JobStatus" AS ENUM ('PENDING', 'QUEUED', 'RUNNING', 'COMPLETED', 'FAILED', 'CANCELLED', 'ERROR');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "users" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"password_hash" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_login_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "organizations" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"plan" TEXT NOT NULL DEFAULT 'free',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "organizations_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "org_memberships" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"role" "Role" NOT NULL,
|
||||
|
||||
CONSTRAINT "org_memberships_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "projects" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"settings_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "projects_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "checks" (
|
||||
"id" TEXT NOT NULL,
|
||||
"project_id" TEXT NOT NULL,
|
||||
"input_url" TEXT NOT NULL,
|
||||
"method" TEXT NOT NULL DEFAULT 'GET',
|
||||
"headers_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"user_agent" TEXT,
|
||||
"started_at" TIMESTAMP(3) NOT NULL,
|
||||
"finished_at" TIMESTAMP(3),
|
||||
"status" "CheckStatus" NOT NULL,
|
||||
"final_url" TEXT,
|
||||
"total_time_ms" INTEGER,
|
||||
"report_id" TEXT,
|
||||
|
||||
CONSTRAINT "checks_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "hops" (
|
||||
"id" TEXT NOT NULL,
|
||||
"check_id" TEXT NOT NULL,
|
||||
"hop_index" INTEGER NOT NULL,
|
||||
"url" TEXT NOT NULL,
|
||||
"scheme" TEXT,
|
||||
"status_code" INTEGER,
|
||||
"redirect_type" "RedirectType" NOT NULL,
|
||||
"latency_ms" INTEGER,
|
||||
"content_type" TEXT,
|
||||
"reason" TEXT,
|
||||
"response_headers_json" JSONB NOT NULL DEFAULT '{}',
|
||||
|
||||
CONSTRAINT "hops_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ssl_inspections" (
|
||||
"id" TEXT NOT NULL,
|
||||
"check_id" TEXT NOT NULL,
|
||||
"host" TEXT NOT NULL,
|
||||
"valid_from" TIMESTAMP(3),
|
||||
"valid_to" TIMESTAMP(3),
|
||||
"days_to_expiry" INTEGER,
|
||||
"issuer" TEXT,
|
||||
"protocol" TEXT,
|
||||
"warnings_json" JSONB NOT NULL DEFAULT '[]',
|
||||
|
||||
CONSTRAINT "ssl_inspections_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "seo_flags" (
|
||||
"id" TEXT NOT NULL,
|
||||
"check_id" TEXT NOT NULL,
|
||||
"robots_txt_status" TEXT,
|
||||
"robots_txt_rules_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"meta_robots" TEXT,
|
||||
"canonical_url" TEXT,
|
||||
"sitemap_present" BOOLEAN NOT NULL DEFAULT false,
|
||||
"noindex" BOOLEAN NOT NULL DEFAULT false,
|
||||
"nofollow" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "seo_flags_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "security_flags" (
|
||||
"id" TEXT NOT NULL,
|
||||
"check_id" TEXT NOT NULL,
|
||||
"safe_browsing_status" TEXT,
|
||||
"mixed_content" "MixedContent" NOT NULL DEFAULT 'NONE',
|
||||
"https_to_http" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "security_flags_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "reports" (
|
||||
"id" TEXT NOT NULL,
|
||||
"check_id" TEXT NOT NULL,
|
||||
"markdown_path" TEXT,
|
||||
"pdf_path" TEXT,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "reports_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "bulk_jobs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"organization_id" TEXT,
|
||||
"project_id" TEXT NOT NULL,
|
||||
"upload_path" TEXT NOT NULL,
|
||||
"status" "JobStatus" NOT NULL,
|
||||
"total_urls" INTEGER NOT NULL DEFAULT 0,
|
||||
"processed_urls" INTEGER NOT NULL DEFAULT 0,
|
||||
"successful_urls" INTEGER NOT NULL DEFAULT 0,
|
||||
"failed_urls" INTEGER NOT NULL DEFAULT 0,
|
||||
"config_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"urls_json" JSONB,
|
||||
"results_json" JSONB,
|
||||
"progress_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"started_at" TIMESTAMP(3),
|
||||
"finished_at" TIMESTAMP(3),
|
||||
"completed_at" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "bulk_jobs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "api_keys" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"token_hash" TEXT NOT NULL,
|
||||
"perms_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"rate_limit_quota" INTEGER NOT NULL DEFAULT 1000,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "api_keys_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "audit_logs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"org_id" TEXT NOT NULL,
|
||||
"actor_user_id" TEXT,
|
||||
"action" TEXT NOT NULL,
|
||||
"entity" TEXT NOT NULL,
|
||||
"entity_id" TEXT NOT NULL,
|
||||
"meta_json" JSONB NOT NULL DEFAULT '{}',
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "org_memberships_org_id_user_id_key" ON "org_memberships"("org_id", "user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "checks_project_id_started_at_idx" ON "checks"("project_id", "started_at" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "hops_check_id_hop_index_idx" ON "hops"("check_id", "hop_index");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "seo_flags_check_id_key" ON "seo_flags"("check_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "security_flags_check_id_key" ON "security_flags"("check_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "api_keys_token_hash_key" ON "api_keys"("token_hash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "api_keys_token_hash_idx" ON "api_keys"("token_hash");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "org_memberships" ADD CONSTRAINT "org_memberships_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "org_memberships" ADD CONSTRAINT "org_memberships_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "projects" ADD CONSTRAINT "projects_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "checks" ADD CONSTRAINT "checks_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "hops" ADD CONSTRAINT "hops_check_id_fkey" FOREIGN KEY ("check_id") REFERENCES "checks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ssl_inspections" ADD CONSTRAINT "ssl_inspections_check_id_fkey" FOREIGN KEY ("check_id") REFERENCES "checks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "seo_flags" ADD CONSTRAINT "seo_flags_check_id_fkey" FOREIGN KEY ("check_id") REFERENCES "checks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "security_flags" ADD CONSTRAINT "security_flags_check_id_fkey" FOREIGN KEY ("check_id") REFERENCES "checks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "reports" ADD CONSTRAINT "reports_check_id_fkey" FOREIGN KEY ("check_id") REFERENCES "checks"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "bulk_jobs" ADD CONSTRAINT "bulk_jobs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "bulk_jobs" ADD CONSTRAINT "bulk_jobs_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "bulk_jobs" ADD CONSTRAINT "bulk_jobs_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "api_keys" ADD CONSTRAINT "api_keys_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_org_id_fkey" FOREIGN KEY ("org_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_actor_user_id_fkey" FOREIGN KEY ("actor_user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
3
packages/database/prisma/migrations/migration_lock.toml
Normal file
3
packages/database/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