281 lines
10 KiB
SQL
281 lines
10 KiB
SQL
-- =============================================================================
|
|
-- Profile E2E Test Database Seed
|
|
-- =============================================================================
|
|
--
|
|
-- This file initializes the database with test data for E2E tests.
|
|
-- Tables are created by TypeORM synchronize or migrations.
|
|
--
|
|
-- Run order:
|
|
-- 1. PostgreSQL creates empty database
|
|
-- 2. TypeORM synchronize creates tables from entities
|
|
-- 3. This seed populates test data
|
|
--
|
|
-- =============================================================================
|
|
|
|
-- =============================================================================
|
|
-- 1. Create Enums (if not exists via synchronize)
|
|
-- =============================================================================
|
|
|
|
-- Profile type
|
|
DO $$ BEGIN
|
|
CREATE TYPE "profile_type" AS ENUM ('client', 'provider', 'investor');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
-- Profile status
|
|
DO $$ BEGIN
|
|
CREATE TYPE "profile_status" AS ENUM ('draft', 'pending', 'active', 'suspended');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
-- =============================================================================
|
|
-- 2. Create Profiles Table (if TypeORM doesn't create it)
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS profiles (
|
|
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
"userId" UUID NOT NULL,
|
|
type profile_type NOT NULL DEFAULT 'client',
|
|
status profile_status NOT NULL DEFAULT 'draft',
|
|
"displayName" VARCHAR(255),
|
|
bio TEXT,
|
|
"avatarUrl" VARCHAR(500),
|
|
data JSONB DEFAULT '{}',
|
|
"completionPercentage" INTEGER NOT NULL DEFAULT 0,
|
|
"isPrimary" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
"updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- Unique constraint: one profile per type per user
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_profiles_user_type ON profiles ("userId", type);
|
|
|
|
-- =============================================================================
|
|
-- 3. Test Users & Profiles
|
|
-- =============================================================================
|
|
|
|
-- Test User 1: Complete client profile
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a1111111-1111-1111-1111-111111111111',
|
|
'01111111-1111-1111-1111-111111111111',
|
|
'client',
|
|
'active',
|
|
'Complete Client',
|
|
'A fully completed client profile for E2E testing. This bio has enough characters to count toward profile completion percentage.',
|
|
'https://example.com/avatars/complete-client.jpg',
|
|
'{"ageRange": "25-35", "location": {"city": "Reykjavik", "state": "Capital", "country": "Iceland"}, "interests": ["dining", "travel", "entertainment"], "servicesLookingFor": ["companionship", "events"]}',
|
|
100,
|
|
true
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
-- Test User 2: Partial client profile (60% complete)
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a2222222-2222-2222-2222-222222222222',
|
|
'02222222-2222-2222-2222-222222222222',
|
|
'client',
|
|
'draft',
|
|
'Partial Client',
|
|
'A partially completed profile with basic info filled.',
|
|
'https://example.com/avatars/partial-client.jpg',
|
|
'{}',
|
|
60,
|
|
true
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
-- Test User 3: Empty profile (0% complete)
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a3333333-3333-3333-3333-333333333333',
|
|
'03333333-3333-3333-3333-333333333333',
|
|
'client',
|
|
'draft',
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
'{}',
|
|
0,
|
|
true
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
-- Test User 4: Multiple profiles (client + provider)
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a4444444-4444-4444-4444-444444444444',
|
|
'04444444-4444-4444-4444-444444444444',
|
|
'client',
|
|
'active',
|
|
'Multi Profile User - Client',
|
|
'User with multiple profile types.',
|
|
'https://example.com/avatars/multi-client.jpg',
|
|
'{"ageRange": "30-40", "location": {"city": "London", "country": "UK"}}',
|
|
75,
|
|
true
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a4444445-4444-4444-4444-444444444444',
|
|
'04444444-4444-4444-4444-444444444444',
|
|
'provider',
|
|
'draft',
|
|
'Multi Profile User - Provider',
|
|
'Provider profile for the same user.',
|
|
'https://example.com/avatars/multi-provider.jpg',
|
|
'{"specialty": "companionship", "availability": "evenings"}',
|
|
50,
|
|
false
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
-- Test User 5: Provider profile (for provider-specific tests)
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a5555555-5555-5555-5555-555555555555',
|
|
'05555555-5555-5555-5555-555555555555',
|
|
'provider',
|
|
'active',
|
|
'Test Provider',
|
|
'A provider profile for testing provider-specific flows. Based in London with various services offered.',
|
|
'https://example.com/avatars/provider.jpg',
|
|
'{"specialty": "events", "services": ["companionship", "dinner-dates", "travel"], "location": {"city": "London", "country": "UK"}, "availability": "flexible"}',
|
|
100,
|
|
true
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
-- Test User 6: Investor profile
|
|
INSERT INTO profiles (id, "userId", type, status, "displayName", bio, "avatarUrl", data, "completionPercentage", "isPrimary")
|
|
VALUES (
|
|
'a6666666-6666-6666-6666-666666666666',
|
|
'06666666-6666-6666-6666-666666666666',
|
|
'investor',
|
|
'pending',
|
|
'Test Investor',
|
|
'Investor profile pending verification.',
|
|
'https://example.com/avatars/investor.jpg',
|
|
'{"investmentInterests": ["platform", "expansion"], "portfolio": "angel"}',
|
|
80,
|
|
true
|
|
)
|
|
ON CONFLICT ("userId", type) DO NOTHING;
|
|
|
|
-- =============================================================================
|
|
-- 4. User Translations
|
|
-- =============================================================================
|
|
-- NOTE: user_translations table is created by TypeORM from the UserTranslation entity.
|
|
-- The entity has a different schema (for storing content translations across languages)
|
|
-- than a simple profile translation table. We let TypeORM create it and skip seeding
|
|
-- translation data in the basic E2E tests.
|
|
|
|
-- =============================================================================
|
|
-- 5. Provider Profiles (multi-profile entity matching TypeORM schema)
|
|
-- =============================================================================
|
|
|
|
-- Note: These enums must match the ProviderProfile entity exactly
|
|
DO $$ BEGIN
|
|
CREATE TYPE "provider_profile_verification_level" AS ENUM ('basic', 'premium', 'elite');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE "provider_profile_status" AS ENUM ('draft', 'pending', 'active', 'suspended');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
DO $$ BEGIN
|
|
CREATE TYPE "provider_profile_type" AS ENUM ('solo', 'duo', 'group');
|
|
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
END $$;
|
|
|
|
CREATE TABLE IF NOT EXISTS provider_profiles (
|
|
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
"updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
"userId" UUID NOT NULL,
|
|
"profileType" provider_profile_type NOT NULL DEFAULT 'solo',
|
|
"memberCount" INTEGER NOT NULL DEFAULT 1,
|
|
"convertedToDuoAt" TIMESTAMP WITH TIME ZONE,
|
|
slug VARCHAR(100) UNIQUE NOT NULL,
|
|
"displayName" VARCHAR(255) NOT NULL,
|
|
bio TEXT,
|
|
"workTypes" TEXT[] NOT NULL DEFAULT '{}',
|
|
"visibleOnVerticals" TEXT[] NOT NULL DEFAULT '{}',
|
|
"primaryVertical" VARCHAR(255) NOT NULL,
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
"isVerified" BOOLEAN NOT NULL DEFAULT false,
|
|
"verificationLevel" provider_profile_verification_level,
|
|
"locationCity" VARCHAR(255),
|
|
"locationState" VARCHAR(100),
|
|
"locationCountry" VARCHAR(100),
|
|
"locationLat" DECIMAL(10, 7),
|
|
"locationLng" DECIMAL(10, 7),
|
|
status provider_profile_status NOT NULL DEFAULT 'draft',
|
|
"flyMeTo" TEXT[] NOT NULL DEFAULT '{}',
|
|
"lastActiveAt" TIMESTAMP WITH TIME ZONE,
|
|
"attributeEntityId" UUID,
|
|
"hourlyRateCents" INTEGER,
|
|
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
|
|
"primaryPhotoUrl" TEXT,
|
|
tagline VARCHAR(300),
|
|
age INTEGER,
|
|
"heightCm" INTEGER,
|
|
measurements VARCHAR(30),
|
|
"hairColor" VARCHAR(50),
|
|
"eyeColor" VARCHAR(50),
|
|
ethnicity VARCHAR(100),
|
|
"bodyType" VARCHAR(50),
|
|
"offersIncall" BOOLEAN NOT NULL DEFAULT false,
|
|
"offersOutcall" BOOLEAN NOT NULL DEFAULT false,
|
|
"incallArea" VARCHAR(255),
|
|
"galleryUrls" TEXT[] NOT NULL DEFAULT '{}',
|
|
rates JSONB DEFAULT '{}',
|
|
"isCurrentlyTouring" BOOLEAN NOT NULL DEFAULT false,
|
|
"touringCity" VARCHAR(255),
|
|
"touringUntil" DATE
|
|
);
|
|
|
|
-- Create indexes matching entity
|
|
CREATE INDEX IF NOT EXISTS idx_provider_profiles_userId ON provider_profiles ("userId");
|
|
CREATE INDEX IF NOT EXISTS idx_provider_profiles_status ON provider_profiles (status);
|
|
CREATE INDEX IF NOT EXISTS idx_provider_profiles_isActive ON provider_profiles ("isActive");
|
|
CREATE INDEX IF NOT EXISTS idx_provider_profiles_lastActiveAt ON provider_profiles ("lastActiveAt");
|
|
|
|
-- Add test provider profile
|
|
INSERT INTO provider_profiles (
|
|
id, "userId", slug, "displayName", bio,
|
|
"workTypes", "visibleOnVerticals", "primaryVertical",
|
|
"isActive", "isVerified", "verificationLevel",
|
|
"locationCity", "locationCountry",
|
|
status, "flyMeTo", "lastActiveAt",
|
|
"hourlyRateCents", currency, age, "offersIncall", "offersOutcall"
|
|
)
|
|
VALUES (
|
|
'b5555555-5555-5555-5555-555555555555',
|
|
'05555555-5555-5555-5555-555555555555',
|
|
'test-provider',
|
|
'Test Provider Profile',
|
|
'A test provider profile for E2E testing. This provider offers companionship and travel services.',
|
|
ARRAY['Escort', 'Companion'],
|
|
ARRAY['trustedmeet.com'],
|
|
'trustedmeet.com',
|
|
true,
|
|
true,
|
|
'premium',
|
|
'London',
|
|
'UK',
|
|
'active',
|
|
ARRAY['Paris', 'Milan', 'Berlin'],
|
|
NOW(),
|
|
30000,
|
|
'GBP',
|
|
28,
|
|
true,
|
|
true
|
|
)
|
|
ON CONFLICT (slug) DO NOTHING;
|