UNPKG

@ideal-photography/shared

Version:

Shared GraphQL (Apollo Server v5) and Mongoose logic for Ideal Photography PWAs: users, products, services, bookings, orders/cart, galleries, reviews, notifications, campaigns, settings, and audit logs.

675 lines (599 loc) 15.6 kB
import { gql } from 'graphql-tag'; const campaignTypeDefs = gql` # Campaign Types type Campaign { _id: ID! uuid: String! name: String! title: String! subtitle: String description: String type: CampaignType! placement: CampaignPlacement! priority: Int! content: CampaignContent! ctas: [CTA!]! schedule: CampaignSchedule! status: CampaignStatus! isActive: Boolean! autoActivate: Boolean! autoDeactivate: Boolean! targeting: CampaignTargeting! themeOverride: ThemeOverride! analytics: CampaignAnalytics! settings: CampaignSettings! createdBy: User! lastEditedBy: User approvedBy: User approvedAt: String tags: [String!]! notes: String version: Int! isScheduled: Boolean! isExpired: Boolean! isCurrentlyActive: Boolean! daysRemaining: Int ctr: Float! createdAt: String! updatedAt: String! } type CampaignContent { images: CampaignImages! headline: String subheadline: String bodyText: String textColor: String! backgroundColor: String overlayOpacity: Float! blur: Float! customStyles: String } type CampaignImages { desktop: String mobile: String tablet: String thumbnail: String } type CTA { label: String! href: String! variant: CTAVariant! target: CTATarget! icon: String position: CTAPosition! } type CampaignSchedule { startDate: String! endDate: String timezone: String! isRecurring: Boolean! recurrence: RecurrenceType recurrenceEnd: String # Advanced scheduling fields isQueued: Boolean! queuePosition: Int autoActivate: Boolean! autoDeactivate: Boolean! activationDelay: Int # minutes deactivationDelay: Int # minutes maxOccurrences: Int currentOccurrences: Int lastOccurrence: String nextOccurrence: String isActive: Boolean! isScheduled: Boolean! priority: SchedulePriority! conflictResolution: ConflictResolution! allowOverlap: Boolean! # Recurrence details recurrenceDetails: RecurrenceDetails } type RecurrenceDetails { frequency: Int! # Every X days/weeks/months/years daysOfWeek: [Int!] # 0-6 (Sunday-Saturday) dayOfMonth: Int # 1-31 weekOfMonth: Int # 1-5 (first, second, third, fourth, last) monthOfYear: Int # 1-12 endAfterOccurrences: Int endOnDate: String } type CampaignTargeting { # User Role Targeting userRoles: [UserRole!]! userRoleGroups: [String!]! # Custom role groups like "premium", "enterprise" excludeUserRoles: [UserRole!]! # Roles to explicitly exclude # User Behavior & Status Targeting newUsers: Boolean! returningUsers: Boolean! verifiedUsers: Boolean! userActivityLevel: UserActivityLevel! # active, inactive, dormant userEngagementScore: EngagementScore! # low, medium, high, premium userLifetimeValue: LifetimeValueRange! # low, medium, high, premium # User Account Targeting accountAge: AccountAgeRange! # new, young, established, veteran subscriptionStatus: [SubscriptionStatus!]! # free, basic, premium, enterprise accountVerificationStatus: [VerificationStatus!]! # unverified, email_verified, phone_verified, fully_verified # Geographic Targeting countries: [String!]! cities: [String!]! regions: [String!]! # States, provinces, etc. postalCodes: [String!]! radius: Int # miles/km from specific location locationPrecision: LocationPrecision! # exact, city, region, country # Device & Technical Targeting deviceType: [DeviceType!]! # mobile, tablet, desktop browser: [String!]! # chrome, firefox, safari, edge operatingSystem: [String!]! # windows, mac, ios, android screenResolution: [String!]! # 1920x1080, 1366x768, etc. # Behavioral Targeting userInterests: [String!]! # Interest tags from user profile purchaseHistory: [String!]! # Product categories purchased browsingBehavior: [BrowsingBehavior!]! # frequent_visitor, cart_abandoner, etc. lastActivity: LastActivity! # recent, moderate, inactive # A/B Testing & Personalization abTestGroup: String # A/B test group assignment personalizationRules: [PersonalizationRule!]! # Dynamic content rules # Frequency & Timing maxFrequency: Int # max impressions per user minTimeBetweenViews: Int # minutes between views timeOfDay: [TimeOfDay!]! # morning, afternoon, evening, night dayOfWeek: [DayOfWeek!]! # monday, tuesday, etc. # Advanced User Targeting userSegments: [String!]! # Custom user segments customAttributes: [CustomAttribute!]! # Dynamic user attributes excludeExistingCustomers: Boolean! # Exclude current customers excludeSubscribers: Boolean! # Exclude newsletter subscribers retargeting: Boolean! # Retargeting campaigns } # Enhanced targeting enums and types enum UserRole { guest user premium_user admin moderator content_creator business_owner enterprise_user } enum UserActivityLevel { active moderate inactive dormant } enum EngagementScore { low medium high premium } enum LifetimeValueRange { low medium high premium } enum AccountAgeRange { new young established veteran } enum SubscriptionStatus { free basic premium enterprise } enum VerificationStatus { unverified email_verified phone_verified fully_verified } enum LocationPrecision { exact city region country } enum DeviceType { mobile tablet desktop } enum BrowsingBehavior { frequent_visitor cart_abandoner window_shopper power_user casual_browser } enum LastActivity { recent moderate inactive } enum TimeOfDay { morning afternoon evening night } enum DayOfWeek { monday tuesday wednesday thursday friday saturday sunday } type PersonalizationRule { condition: String! # User attribute condition action: String! # Content modification action value: String # Dynamic value } type CustomAttribute { key: String! # Attribute name value: String! # Attribute value operator: ComparisonOperator! # Comparison operator } enum ComparisonOperator { equals not_equals contains not_contains greater_than less_than greater_than_or_equal less_than_or_equal in not_in } type ThemeOverride { enabled: Boolean! colorScheme: ColorScheme logo: String favicon: String } type ColorScheme { primary: String secondary: String accent: String background: String text: String } type CampaignAnalytics { impressions: Int! clicks: Int! conversions: Int! ctr: Float! conversionRate: Float! ctaClicks: [CTAClick!]! } type CTAClick { label: String! clicks: Int! } type CampaignSettings { showOnMobile: Boolean! showOnTablet: Boolean! showOnDesktop: Boolean! autoPlay: Boolean! interval: Int! showDots: Boolean! showArrows: Boolean! dismissible: Boolean! sticky: Boolean! animation: AnimationType! animationDuration: Int! } # Enums enum CampaignType { hero_carousel banner popup notification theme_override } enum CampaignPlacement { home_hero top_banner sidebar footer popup_modal notification_bar } enum CampaignStatus { draft scheduled active paused completed cancelled } enum CTAVariant { primary secondary outline ghost whatsapp } enum CTATarget { _self _blank } enum CTAPosition { left center right } enum RecurrenceType { daily weekly monthly yearly } enum SchedulePriority { low normal high urgent } enum ConflictResolution { skip replace queue overlap } enum AnimationType { fade slide zoom none } # Input Types input CreateCampaignInput { name: String! title: String! subtitle: String description: String type: CampaignType! placement: CampaignPlacement! priority: Int = 0 content: CampaignContentInput! ctas: [CTAInput!]! schedule: CampaignScheduleInput! targeting: CampaignTargetingInput themeOverride: ThemeOverrideInput settings: CampaignSettingsInput tags: [String!] notes: String } input UpdateCampaignInput { name: String title: String subtitle: String description: String type: CampaignType placement: CampaignPlacement priority: Int content: CampaignContentInput ctas: [CTAInput!] schedule: CampaignScheduleInput targeting: CampaignTargetingInput themeOverride: ThemeOverrideInput settings: CampaignSettingsInput tags: [String!] notes: String } input CampaignContentInput { images: CampaignImagesInput headline: String subheadline: String bodyText: String textColor: String = "#FFFFFF" backgroundColor: String overlayOpacity: Float = 0.3 blur: Float = 0.1 customStyles: String } input CampaignImagesInput { desktop: String mobile: String tablet: String thumbnail: String } input CTAInput { label: String! href: String! variant: CTAVariant = primary target: CTATarget = _self icon: String position: CTAPosition = center } input CampaignScheduleInput { startDate: String! endDate: String timezone: String = "UTC" isRecurring: Boolean = false recurrence: RecurrenceType recurrenceEnd: String # Advanced scheduling fields isQueued: Boolean = false queuePosition: Int autoActivate: Boolean = false autoDeactivate: Boolean = false activationDelay: Int = 0 deactivationDelay: Int = 0 maxOccurrences: Int currentOccurrences: Int lastOccurrence: String nextOccurrence: String isActive: Boolean = false isScheduled: Boolean = false priority: SchedulePriority = normal conflictResolution: ConflictResolution = queue allowOverlap: Boolean = false # Recurrence details recurrenceDetails: RecurrenceDetailsInput } input RecurrenceDetailsInput { frequency: Int = 1 daysOfWeek: [Int!] = [] dayOfMonth: Int weekOfMonth: Int monthOfYear: Int endAfterOccurrences: Int endOnDate: String } input CampaignTargetingInput { # User Role Targeting userRoles: [UserRole!] = [] userRoleGroups: [String!] = [] excludeUserRoles: [UserRole!] = [] # User Behavior & Status Targeting newUsers: Boolean = false returningUsers: Boolean = false verifiedUsers: Boolean = false userActivityLevel: UserActivityLevel userEngagementScore: EngagementScore userLifetimeValue: LifetimeValueRange # User Account Targeting accountAge: AccountAgeRange subscriptionStatus: [SubscriptionStatus!] = [] accountVerificationStatus: [VerificationStatus!] = [] # Geographic Targeting countries: [String!] = [] cities: [String!] = [] regions: [String!] = [] postalCodes: [String!] = [] radius: Int locationPrecision: LocationPrecision # Device & Technical Targeting deviceType: [DeviceType!] = [] browser: [String!] = [] operatingSystem: [String!] = [] screenResolution: [String!] = [] # Behavioral Targeting userInterests: [String!] = [] purchaseHistory: [String!] = [] browsingBehavior: [BrowsingBehavior!] = [] lastActivity: LastActivity # A/B Testing & Personalization abTestGroup: String personalizationRules: [PersonalizationRuleInput!] = [] # Frequency & Timing maxFrequency: Int minTimeBetweenViews: Int timeOfDay: [TimeOfDay!] = [] dayOfWeek: [DayOfWeek!] = [] # Advanced User Targeting userSegments: [String!] = [] customAttributes: [CustomAttributeInput!] = [] excludeExistingCustomers: Boolean = false excludeSubscribers: Boolean = false retargeting: Boolean = false } input PersonalizationRuleInput { condition: String! action: String! value: String } input CustomAttributeInput { key: String! value: String! operator: ComparisonOperator! } input ThemeOverrideInput { enabled: Boolean = false colorScheme: ColorSchemeInput logo: String favicon: String } input ColorSchemeInput { primary: String secondary: String accent: String background: String text: String } input CampaignSettingsInput { showOnMobile: Boolean = true showOnTablet: Boolean = true showOnDesktop: Boolean = true autoPlay: Boolean = true interval: Int = 5000 showDots: Boolean = true showArrows: Boolean = true dismissible: Boolean = false sticky: Boolean = false animation: AnimationType = fade animationDuration: Int = 300 } input CampaignFilter { type: CampaignType placement: CampaignPlacement status: CampaignStatus isActive: Boolean isScheduled: Boolean isExpired: Boolean createdBy: ID tags: [String!] } # Campaign Queries type Query { campaigns( status: CampaignStatus placement: CampaignPlacement type: CampaignType limit: Int offset: Int ): [Campaign!]! campaign(id: ID!): Campaign activeCampaigns(placement: String, type: String): [Campaign!]! scheduledCampaigns: [Campaign!]! campaignsByPlacement(placement: CampaignPlacement!): [Campaign!]! campaignsByType(type: CampaignType!): [Campaign!]! # Advanced scheduling queries queuedCampaigns: [Campaign!]! scheduledCampaignsByDate(startDate: String!, endDate: String!): [Campaign!]! campaignsWithConflicts: [Campaign!]! recurringCampaigns: [Campaign!]! campaignsByPriority(priority: SchedulePriority!): [Campaign!]! upcomingCampaigns(days: Int = 7): [Campaign!]! expiredCampaigns: [Campaign!]! # Queue management queuePosition(campaignId: ID!): Int queueLength: Int! nextInQueue: Campaign } # Campaign Mutations type Mutation { createCampaign(input: CreateCampaignInput!): Campaign! updateCampaign(id: ID!, input: UpdateCampaignInput!): Campaign! deleteCampaign(id: ID!): Boolean! activateCampaign(id: ID!): Campaign! deactivateCampaign(id: ID!): Campaign! approveCampaign(id: ID!): Campaign! duplicateCampaign(id: ID!): Campaign! # Advanced scheduling mutations scheduleCampaign(id: ID!, schedule: CampaignScheduleInput!): Campaign! unscheduleCampaign(id: ID!): Campaign! queueCampaign(id: ID!, priority: SchedulePriority = normal): Campaign! dequeueCampaign(id: ID!): Campaign! moveInQueue(id: ID!, newPosition: Int!): Campaign! autoActivateCampaign(id: ID!): Campaign! autoDeactivateCampaign(id: ID!): Campaign! updateRecurrence(id: ID!, recurrenceDetails: RecurrenceDetailsInput!): Campaign! resolveScheduleConflict(id: ID!, resolution: ConflictResolution!): Campaign! # Bulk operations bulkActivateCampaigns(ids: [ID!]!): [Campaign!]! bulkDeactivateCampaigns(ids: [ID!]!): [Campaign!]! bulkDeleteCampaigns(ids: [ID!]!): Boolean! bulkScheduleCampaigns(ids: [ID!]!, schedule: CampaignScheduleInput!): [Campaign!]! } `; export default campaignTypeDefs;