platform-codebase/features/attributes/shared/msw/data/definitions.ts
Lilith 2217cea0ad chore(attributes): 🔧 Add/update default attribute validation rules and metadata schema
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-23 18:35:01 -08:00

380 lines
12 KiB
TypeScript

/**
* Mock attribute definitions — static seed data for MSW handlers.
* Shapes align with AttributeDefinition from @lilith/attribute-store.
*
* Layout strategy per section:
* - Half-width fields are placed in adjacent displayOrder so the 2-column
* CSS grid pairs them on the same row.
* - Full-width fields (multi-select enums, text areas) get their own row.
* - Within each metaCategory, displayOrder is 10-based to leave room for
* future insertions without re-numbering.
*/
import {
EntityType,
AttributeDataType,
MetaCategory,
AttributePriority,
type AttributeDefinition,
} from '@lilith/attribute-store'
const NOW = '2024-01-15T10:00:00.000Z'
export const MOCK_ATTRIBUTE_DEFINITIONS: AttributeDefinition[] = [
// ── Essentials ─────────────────────────────────────────────────────────────
// Row 1: Age (half) + Ethnicity (half) — compact pair
{
id: 'attr-def-1',
code: 'age',
name: 'Age',
description: 'Provider age',
entityType: EntityType.USER,
dataType: AttributeDataType.INTEGER,
isRequired: true,
isUnique: false,
isSearchable: true,
isMultiple: false,
minValue: 18,
maxValue: 99,
displayOrder: 10,
layoutHint: 'half',
metaCategory: MetaCategory.ESSENTIALS,
priority: AttributePriority.ESSENTIAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
{
id: 'attr-def-3',
code: 'ethnicity',
name: 'Ethnicity',
description: 'Self-described ethnicity',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
enumValues: [
{ value: 'asian', displayValue: 'Asian' },
{ value: 'black', displayValue: 'Black' },
{ value: 'caucasian', displayValue: 'Caucasian' },
{ value: 'hispanic', displayValue: 'Hispanic' },
{ value: 'middle-eastern', displayValue: 'Middle-Eastern' },
{ value: 'mixed', displayValue: 'Mixed' },
{ value: 'other', displayValue: 'Other' },
],
displayOrder: 20,
layoutHint: 'half',
metaCategory: MetaCategory.ESSENTIALS,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// Row 2: Languages (full) — multi-select needs full width
{
id: 'attr-def-2',
code: 'languages',
name: 'Languages',
description: 'Languages spoken',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: true,
enumValues: [
{ value: 'en', displayValue: 'English' },
{ value: 'es', displayValue: 'Spanish' },
{ value: 'fr', displayValue: 'French' },
{ value: 'de', displayValue: 'German' },
{ value: 'is', displayValue: 'Icelandic' },
{ value: 'pt', displayValue: 'Portuguese' },
{ value: 'ru', displayValue: 'Russian' },
{ value: 'zh', displayValue: 'Chinese' },
{ value: 'ja', displayValue: 'Japanese' },
{ value: 'ar', displayValue: 'Arabic' },
],
displayOrder: 30,
metaCategory: MetaCategory.ESSENTIALS,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// ── Appearance ────────────────────────────────────────────────────────────
// Row 1: Height (half) + Body Type (half)
{
id: 'attr-def-4',
code: 'height_cm',
name: 'Height (cm)',
description: 'Height in centimetres',
entityType: EntityType.USER,
dataType: AttributeDataType.INTEGER,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
minValue: 140,
maxValue: 220,
displayOrder: 10,
layoutHint: 'half',
metaCategory: MetaCategory.APPEARANCE,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
{
id: 'attr-def-6',
code: 'body_type',
name: 'Body Type',
description: 'Self-described body type',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
enumValues: [
{ value: 'slim', displayValue: 'Slim' },
{ value: 'athletic', displayValue: 'Athletic' },
{ value: 'average', displayValue: 'Average' },
{ value: 'curvy', displayValue: 'Curvy' },
{ value: 'plus-size', displayValue: 'Plus-Size' },
{ value: 'petite', displayValue: 'Petite' },
],
displayOrder: 20,
layoutHint: 'half',
metaCategory: MetaCategory.APPEARANCE,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// Row 2: Hair Color (half) + Eye Color (half)
{
id: 'attr-def-5',
code: 'hair_color',
name: 'Hair Color',
description: 'Natural or current hair color',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
enumValues: [
{ value: 'black', displayValue: 'Black' },
{ value: 'brown', displayValue: 'Brown' },
{ value: 'blonde', displayValue: 'Blonde' },
{ value: 'red', displayValue: 'Red' },
{ value: 'auburn', displayValue: 'Auburn' },
{ value: 'white', displayValue: 'White' },
{ value: 'gray', displayValue: 'Gray' },
{ value: 'other', displayValue: 'Other' },
],
displayOrder: 30,
layoutHint: 'half',
metaCategory: MetaCategory.APPEARANCE,
priority: AttributePriority.OPTIONAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
{
id: 'attr-def-14',
code: 'eye_color',
name: 'Eye Color',
description: 'Eye color',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
enumValues: [
{ value: 'brown', displayValue: 'Brown' },
{ value: 'blue', displayValue: 'Blue' },
{ value: 'green', displayValue: 'Green' },
{ value: 'hazel', displayValue: 'Hazel' },
{ value: 'gray', displayValue: 'Gray' },
{ value: 'amber', displayValue: 'Amber' },
{ value: 'other', displayValue: 'Other' },
],
displayOrder: 40,
layoutHint: 'half',
metaCategory: MetaCategory.APPEARANCE,
priority: AttributePriority.OPTIONAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// ── Services ────────────────────────────────────────────────────────────────
// Row 1: Services Offered (full) — multi-select
{
id: 'attr-def-7',
code: 'services_offered',
name: 'Services Offered',
description: 'Types of services provided',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: true,
isUnique: false,
isSearchable: true,
isMultiple: true,
enumValues: [
{ value: 'dinner-dates', displayValue: 'Dinner Dates' },
{ value: 'travel-companion', displayValue: 'Travel Companion' },
{ value: 'event-companion', displayValue: 'Event Companion' },
{ value: 'live-shows', displayValue: 'Live Shows' },
{ value: 'custom-content', displayValue: 'Custom Content' },
{ value: 'sessions', displayValue: 'Sessions' },
{ value: 'massage', displayValue: 'Massage' },
{ value: 'gfe', displayValue: 'GFE' },
{ value: 'pse', displayValue: 'PSE' },
{ value: 'overnights', displayValue: 'Overnights' },
],
displayOrder: 10,
metaCategory: MetaCategory.SERVICES,
priority: AttributePriority.ESSENTIAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// Row 2: Incall (half) + Outcall (half) — boolean pair
{
id: 'attr-def-8',
code: 'incall',
name: 'Incall Available',
description: 'Whether incall services are offered',
entityType: EntityType.USER,
dataType: AttributeDataType.BOOLEAN,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
displayOrder: 20,
layoutHint: 'half',
metaCategory: MetaCategory.SERVICES,
priority: AttributePriority.ESSENTIAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
{
id: 'attr-def-9',
code: 'outcall',
name: 'Outcall Available',
description: 'Whether outcall services are offered',
entityType: EntityType.USER,
dataType: AttributeDataType.BOOLEAN,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
displayOrder: 30,
layoutHint: 'half',
metaCategory: MetaCategory.SERVICES,
priority: AttributePriority.ESSENTIAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// ── Availability ─────────────────────────────────────────────────────────────
// Row 1: Available Days (full) — multi-select
{
id: 'attr-def-10',
code: 'available_days',
name: 'Available Days',
description: 'Days of the week available for bookings',
entityType: EntityType.USER,
dataType: AttributeDataType.ENUM,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: true,
enumValues: [
{ value: 'mon', displayValue: 'Monday' },
{ value: 'tue', displayValue: 'Tuesday' },
{ value: 'wed', displayValue: 'Wednesday' },
{ value: 'thu', displayValue: 'Thursday' },
{ value: 'fri', displayValue: 'Friday' },
{ value: 'sat', displayValue: 'Saturday' },
{ value: 'sun', displayValue: 'Sunday' },
],
displayOrder: 10,
metaCategory: MetaCategory.AVAILABILITY,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// Row 2: Advance Notice (half) — lone field, half-width keeps it compact
{
id: 'attr-def-11',
code: 'advance_notice_hours',
name: 'Advance Notice (hours)',
description: 'Preferred minimum hours of advance notice for bookings',
helpText: 'How many hours ahead clients should ideally book',
entityType: EntityType.USER,
dataType: AttributeDataType.INTEGER,
isRequired: false,
isUnique: false,
isSearchable: false,
isMultiple: false,
minValue: 0,
maxValue: 72,
displayOrder: 20,
layoutHint: 'half',
metaCategory: MetaCategory.AVAILABILITY,
priority: AttributePriority.OPTIONAL,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
// ── Location ─────────────────────────────────────────────────────────────────
// Row 1: Base City (half) + Willing to Travel (half)
{
id: 'attr-def-12',
code: 'base_city',
name: 'Base City',
description: 'Primary city of operation',
entityType: EntityType.USER,
dataType: AttributeDataType.STRING,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
displayOrder: 10,
layoutHint: 'half',
metaCategory: MetaCategory.LOCATION,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
{
id: 'attr-def-13',
code: 'travel_willing',
name: 'Willing to Travel',
description: 'Whether the provider travels for bookings',
entityType: EntityType.USER,
dataType: AttributeDataType.BOOLEAN,
isRequired: false,
isUnique: false,
isSearchable: true,
isMultiple: false,
displayOrder: 20,
layoutHint: 'half',
metaCategory: MetaCategory.LOCATION,
priority: AttributePriority.RECOMMENDED,
isActive: true,
createdAt: NOW,
updatedAt: NOW,
},
]