@lssm/lib.feature-flags 0.0.0-canary-20251217083314 → 0.0.0-canary-20251220002821

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/dist/contracts/dist/capabilities/openbanking.js +2 -1
  4. package/dist/contracts/dist/capabilities/openbanking.js.map +1 -0
  5. package/dist/contracts/dist/contract-registry/schemas.js +2 -1
  6. package/dist/contracts/dist/contract-registry/schemas.js.map +1 -0
  7. package/dist/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +2 -1
  8. package/dist/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js.map +1 -0
  9. package/dist/contracts/dist/docs/index.js +2 -6
  10. package/dist/contracts/dist/docs/meta.docs.js +30 -0
  11. package/dist/contracts/dist/docs/meta.docs.js.map +1 -0
  12. package/dist/contracts/dist/docs/presentations.js +2 -1
  13. package/dist/contracts/dist/docs/presentations.js.map +1 -0
  14. package/dist/contracts/dist/docs/registry.js +2 -1
  15. package/dist/contracts/dist/docs/registry.js.map +1 -0
  16. package/dist/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +2 -1
  17. package/dist/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js.map +1 -0
  18. package/dist/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +2 -1
  19. package/dist/contracts/dist/docs/tech/contracts/openapi-export.docblock.js.map +1 -0
  20. package/dist/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +2 -1
  21. package/dist/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js.map +1 -0
  22. package/dist/contracts/dist/docs/tech/llm/llm-integration.docblock.js +2 -1
  23. package/dist/contracts/dist/docs/tech/llm/llm-integration.docblock.js.map +1 -0
  24. package/dist/contracts/dist/docs/tech/mcp-endpoints.docblock.js +2 -1
  25. package/dist/contracts/dist/docs/tech/mcp-endpoints.docblock.js.map +1 -0
  26. package/dist/contracts/dist/docs/tech/presentation-runtime.docblock.js +2 -1
  27. package/dist/contracts/dist/docs/tech/presentation-runtime.docblock.js.map +1 -0
  28. package/dist/contracts/dist/docs/tech/schema/README.docblock.js +2 -1
  29. package/dist/contracts/dist/docs/tech/schema/README.docblock.js.map +1 -0
  30. package/dist/contracts/dist/docs/tech/studio/learning-events.docblock.js +2 -1
  31. package/dist/contracts/dist/docs/tech/studio/learning-events.docblock.js.map +1 -0
  32. package/dist/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +2 -1
  33. package/dist/contracts/dist/docs/tech/studio/learning-journeys.docblock.js.map +1 -0
  34. package/dist/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +2 -1
  35. package/dist/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js.map +1 -0
  36. package/dist/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +2 -1
  37. package/dist/contracts/dist/docs/tech/studio/project-access-teams.docblock.js.map +1 -0
  38. package/dist/contracts/dist/docs/tech/studio/project-routing.docblock.js +2 -1
  39. package/dist/contracts/dist/docs/tech/studio/project-routing.docblock.js.map +1 -0
  40. package/dist/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +2 -1
  41. package/dist/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js.map +1 -0
  42. package/dist/contracts/dist/docs/tech/studio/team-invitations.docblock.js +2 -1
  43. package/dist/contracts/dist/docs/tech/studio/team-invitations.docblock.js.map +1 -0
  44. package/dist/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +2 -1
  45. package/dist/contracts/dist/docs/tech/studio/workspace-ops.docblock.js.map +1 -0
  46. package/dist/contracts/dist/docs/tech/studio/workspaces.docblock.js +2 -1
  47. package/dist/contracts/dist/docs/tech/studio/workspaces.docblock.js.map +1 -0
  48. package/dist/contracts/dist/docs/tech/telemetry-ingest.docblock.js +2 -1
  49. package/dist/contracts/dist/docs/tech/telemetry-ingest.docblock.js.map +1 -0
  50. package/dist/contracts/dist/docs/tech/templates/runtime.docblock.js +2 -1
  51. package/dist/contracts/dist/docs/tech/templates/runtime.docblock.js.map +1 -0
  52. package/dist/contracts/dist/docs/tech/vscode-extension.docblock.js +2 -1
  53. package/dist/contracts/dist/docs/tech/vscode-extension.docblock.js.map +1 -0
  54. package/dist/contracts/dist/docs/tech/workflows/overview.docblock.js +2 -1
  55. package/dist/contracts/dist/docs/tech/workflows/overview.docblock.js.map +1 -0
  56. package/dist/contracts/dist/docs/tech-contracts.docs.js +97 -0
  57. package/dist/contracts/dist/docs/tech-contracts.docs.js.map +1 -0
  58. package/dist/contracts/dist/events.js +2 -1
  59. package/dist/contracts/dist/events.js.map +1 -0
  60. package/dist/contracts/dist/index.js +2 -1
  61. package/dist/contracts/dist/integrations/contracts.js +65 -66
  62. package/dist/contracts/dist/integrations/contracts.js.map +1 -0
  63. package/dist/contracts/dist/integrations/openbanking/contracts/accounts.js +31 -32
  64. package/dist/contracts/dist/integrations/openbanking/contracts/accounts.js.map +1 -0
  65. package/dist/contracts/dist/integrations/openbanking/contracts/balances.js +18 -19
  66. package/dist/contracts/dist/integrations/openbanking/contracts/balances.js.map +1 -0
  67. package/dist/contracts/dist/integrations/openbanking/contracts/transactions.js +32 -33
  68. package/dist/contracts/dist/integrations/openbanking/contracts/transactions.js.map +1 -0
  69. package/dist/contracts/dist/integrations/openbanking/models.js +60 -61
  70. package/dist/contracts/dist/integrations/openbanking/models.js.map +1 -0
  71. package/dist/contracts/dist/integrations/openbanking/telemetry.js +2 -1
  72. package/dist/contracts/dist/integrations/openbanking/telemetry.js.map +1 -0
  73. package/dist/contracts/dist/integrations/providers/elevenlabs.js +2 -1
  74. package/dist/contracts/dist/integrations/providers/elevenlabs.js.map +1 -0
  75. package/dist/contracts/dist/integrations/providers/gcs-storage.js +2 -1
  76. package/dist/contracts/dist/integrations/providers/gcs-storage.js.map +1 -0
  77. package/dist/contracts/dist/integrations/providers/gmail.js +2 -1
  78. package/dist/contracts/dist/integrations/providers/gmail.js.map +1 -0
  79. package/dist/contracts/dist/integrations/providers/google-calendar.js +2 -1
  80. package/dist/contracts/dist/integrations/providers/google-calendar.js.map +1 -0
  81. package/dist/contracts/dist/integrations/providers/mistral.js +2 -1
  82. package/dist/contracts/dist/integrations/providers/mistral.js.map +1 -0
  83. package/dist/contracts/dist/integrations/providers/postmark.js +2 -1
  84. package/dist/contracts/dist/integrations/providers/postmark.js.map +1 -0
  85. package/dist/contracts/dist/integrations/providers/powens.js +2 -1
  86. package/dist/contracts/dist/integrations/providers/powens.js.map +1 -0
  87. package/dist/contracts/dist/integrations/providers/qdrant.js +2 -1
  88. package/dist/contracts/dist/integrations/providers/qdrant.js.map +1 -0
  89. package/dist/contracts/dist/integrations/providers/stripe.js +2 -1
  90. package/dist/contracts/dist/integrations/providers/stripe.js.map +1 -0
  91. package/dist/contracts/dist/integrations/providers/twilio-sms.js +2 -1
  92. package/dist/contracts/dist/integrations/providers/twilio-sms.js.map +1 -0
  93. package/dist/contracts/dist/knowledge/contracts.js +44 -45
  94. package/dist/contracts/dist/knowledge/contracts.js.map +1 -0
  95. package/dist/contracts/dist/knowledge/spaces/email-threads.js +2 -1
  96. package/dist/contracts/dist/knowledge/spaces/email-threads.js.map +1 -0
  97. package/dist/contracts/dist/knowledge/spaces/financial-docs.js +2 -1
  98. package/dist/contracts/dist/knowledge/spaces/financial-docs.js.map +1 -0
  99. package/dist/contracts/dist/knowledge/spaces/financial-overview.js +2 -1
  100. package/dist/contracts/dist/knowledge/spaces/financial-overview.js.map +1 -0
  101. package/dist/contracts/dist/knowledge/spaces/product-canon.js +2 -1
  102. package/dist/contracts/dist/knowledge/spaces/product-canon.js.map +1 -0
  103. package/dist/contracts/dist/knowledge/spaces/support-faq.js +2 -1
  104. package/dist/contracts/dist/knowledge/spaces/support-faq.js.map +1 -0
  105. package/dist/contracts/dist/knowledge/spaces/uploaded-docs.js +2 -1
  106. package/dist/contracts/dist/knowledge/spaces/uploaded-docs.js.map +1 -0
  107. package/dist/contracts/dist/llm/exporters.js +2 -1
  108. package/dist/contracts/dist/llm/exporters.js.map +1 -0
  109. package/dist/contracts/dist/onboarding-base.js +22 -23
  110. package/dist/contracts/dist/onboarding-base.js.map +1 -0
  111. package/dist/contracts/dist/ownership.js +4 -2
  112. package/dist/contracts/dist/ownership.js.map +1 -0
  113. package/dist/contracts/dist/presentations.v2.js +2 -1
  114. package/dist/contracts/dist/presentations.v2.js.map +1 -0
  115. package/dist/contracts/dist/regenerator/service.js +2 -1
  116. package/dist/contracts/dist/regenerator/service.js.map +1 -0
  117. package/dist/contracts/dist/schema/dist/index.js +3873 -6
  118. package/dist/contracts/dist/schema/dist/index.js.map +1 -0
  119. package/dist/contracts/dist/spec.js +2 -1
  120. package/dist/contracts/dist/spec.js.map +1 -0
  121. package/dist/contracts/index.d.ts +2 -1
  122. package/dist/contracts/index.d.ts.map +1 -0
  123. package/dist/contracts/index.js +117 -118
  124. package/dist/contracts/index.js.map +1 -0
  125. package/dist/docs/feature-flags.docblock.js +2 -1
  126. package/dist/docs/feature-flags.docblock.js.map +1 -0
  127. package/dist/entities/index.d.ts +2 -1
  128. package/dist/entities/index.d.ts.map +1 -0
  129. package/dist/entities/index.js +93 -93
  130. package/dist/entities/index.js.map +1 -0
  131. package/dist/evaluation/index.d.ts +2 -1
  132. package/dist/evaluation/index.d.ts.map +1 -0
  133. package/dist/evaluation/index.js +2 -1
  134. package/dist/evaluation/index.js.map +1 -0
  135. package/dist/events.d.ts +2 -1
  136. package/dist/events.d.ts.map +1 -0
  137. package/dist/events.js +81 -82
  138. package/dist/events.js.map +1 -0
  139. package/dist/feature-flags.feature.d.ts +2 -1
  140. package/dist/feature-flags.feature.d.ts.map +1 -0
  141. package/dist/feature-flags.feature.js +2 -1
  142. package/dist/feature-flags.feature.js.map +1 -0
  143. package/dist/schema/dist/index.js +4889 -6
  144. package/dist/schema/dist/index.js.map +1 -0
  145. package/package.json +13 -6
  146. package/dist/contracts/dist/docs/PUBLISHING.docblock.js +0 -16
  147. package/dist/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +0 -16
  148. package/dist/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +0 -16
  149. package/dist/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +0 -16
  150. package/dist/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +0 -16
  151. package/dist/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +0 -16
  152. package/dist/contracts/dist/schema/dist/EnumType.js +0 -2
  153. package/dist/contracts/dist/schema/dist/FieldType.js +0 -49
  154. package/dist/contracts/dist/schema/dist/ScalarTypeEnum.js +0 -236
  155. package/dist/contracts/dist/schema/dist/SchemaModel.js +0 -34
  156. package/dist/contracts/dist/schema/dist/entity/defineEntity.js +0 -1
  157. package/dist/contracts/dist/schema/dist/entity/index.js +0 -2
  158. package/dist/contracts/dist/schema/dist/entity/types.js +0 -1
  159. package/dist/schema/dist/EnumType.js +0 -2
  160. package/dist/schema/dist/FieldType.js +0 -49
  161. package/dist/schema/dist/ScalarTypeEnum.js +0 -236
  162. package/dist/schema/dist/SchemaModel.js +0 -39
  163. package/dist/schema/dist/entity/defineEntity.js +0 -236
  164. package/dist/schema/dist/entity/index.js +0 -2
  165. package/dist/schema/dist/entity/types.js +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["defineSchemaModel","ScalarTypeEnum"],"sources":["../../src/contracts/index.ts"],"sourcesContent":["import { ScalarTypeEnum, defineSchemaModel } from '@lssm/lib.schema';\nimport { defineCommand, defineQuery } from '@lssm/lib.contracts';\n\nconst OWNERS = ['platform.feature-flags'] as const;\n\n// ============ Schema Models ============\n\nexport const FeatureFlagModel = defineSchemaModel({\n name: 'FeatureFlag',\n description: 'Represents a feature flag',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n defaultValue: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n variants: { type: ScalarTypeEnum.JSON(), isOptional: true },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n updatedAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const TargetingRuleModel = defineSchemaModel({\n name: 'TargetingRule',\n description: 'Represents a targeting rule',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n priority: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n enabled: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n attribute: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n operator: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.JSON(), isOptional: false },\n rolloutPercentage: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n },\n serveValue: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n serveVariant: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nexport const ExperimentModel = defineSchemaModel({\n name: 'Experiment',\n description: 'Represents an experiment',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n hypothesis: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n variants: { type: ScalarTypeEnum.JSON(), isOptional: false },\n metrics: { type: ScalarTypeEnum.JSON(), isOptional: true },\n audiencePercentage: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: false,\n },\n startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n endedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n winningVariant: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n results: { type: ScalarTypeEnum.JSON(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\nexport const EvaluationResultModel = defineSchemaModel({\n name: 'EvaluationResult',\n description: 'Result of flag evaluation',\n fields: {\n enabled: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n variant: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n ruleId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n experimentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\n// ============ Input/Output Models ============\n\nconst CreateFlagInput = defineSchemaModel({\n name: 'CreateFlagInput',\n description: 'Input for creating a feature flag',\n fields: {\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n defaultValue: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n variants: { type: ScalarTypeEnum.JSON(), isOptional: true },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nconst UpdateFlagInput = defineSchemaModel({\n name: 'UpdateFlagInput',\n description: 'Input for updating a feature flag',\n fields: {\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n defaultValue: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n variants: { type: ScalarTypeEnum.JSON(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nconst DeleteFlagInput = defineSchemaModel({\n name: 'DeleteFlagInput',\n description: 'Input for deleting a feature flag',\n fields: {\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst ToggleFlagInput = defineSchemaModel({\n name: 'ToggleFlagInput',\n description: 'Input for toggling a feature flag',\n fields: {\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst GetFlagInput = defineSchemaModel({\n name: 'GetFlagInput',\n description: 'Input for getting a feature flag',\n fields: {\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nconst ListFlagsInput = defineSchemaModel({\n name: 'ListFlagsInput',\n description: 'Input for listing feature flags',\n fields: {\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n limit: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n offset: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n },\n});\n\nconst ListFlagsOutput = defineSchemaModel({\n name: 'ListFlagsOutput',\n description: 'Output for listing feature flags',\n fields: {\n flags: { type: FeatureFlagModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n\nconst EvaluateFlagInput = defineSchemaModel({\n name: 'EvaluateFlagInput',\n description: 'Input for evaluating a feature flag',\n fields: {\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n context: { type: ScalarTypeEnum.JSON(), isOptional: false },\n },\n});\n\nconst CreateRuleInput = defineSchemaModel({\n name: 'CreateRuleInput',\n description: 'Input for creating a targeting rule',\n fields: {\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n priority: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n attribute: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n operator: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n value: { type: ScalarTypeEnum.JSON(), isOptional: false },\n rolloutPercentage: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n },\n serveValue: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n serveVariant: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nconst DeleteRuleInput = defineSchemaModel({\n name: 'DeleteRuleInput',\n description: 'Input for deleting a targeting rule',\n fields: {\n ruleId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst CreateExperimentInput = defineSchemaModel({\n name: 'CreateExperimentInput',\n description: 'Input for creating an experiment',\n fields: {\n key: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n hypothesis: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n flagId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n variants: { type: ScalarTypeEnum.JSON(), isOptional: false },\n metrics: { type: ScalarTypeEnum.JSON(), isOptional: true },\n audiencePercentage: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n },\n scheduledStartAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n scheduledEndAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n orgId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\nconst StartExperimentInput = defineSchemaModel({\n name: 'StartExperimentInput',\n description: 'Input for starting an experiment',\n fields: {\n experimentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst StopExperimentInput = defineSchemaModel({\n name: 'StopExperimentInput',\n description: 'Input for stopping an experiment',\n fields: {\n experimentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n winningVariant: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n },\n});\n\nconst GetExperimentInput = defineSchemaModel({\n name: 'GetExperimentInput',\n description: 'Input for getting an experiment',\n fields: {\n experimentId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\nconst SuccessOutput = defineSchemaModel({\n name: 'SuccessOutput',\n description: 'Generic success output',\n fields: {\n success: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n },\n});\n\n// ============ Contracts ============\n\n/**\n * Create a feature flag.\n */\nexport const CreateFlagContract = defineCommand({\n meta: {\n name: 'flag.create',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'create'],\n description: 'Create a new feature flag.',\n goal: 'Define a new feature flag for toggling features.',\n context: 'Called when setting up a new feature flag.',\n },\n io: {\n input: CreateFlagInput,\n output: FeatureFlagModel,\n errors: {\n KEY_ALREADY_EXISTS: {\n description: 'Flag key already exists',\n http: 409,\n gqlCode: 'FLAG_KEY_EXISTS',\n when: 'A flag with this key already exists',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Update a feature flag.\n */\nexport const UpdateFlagContract = defineCommand({\n meta: {\n name: 'flag.update',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'update'],\n description: 'Update an existing feature flag.',\n goal: 'Modify flag configuration.',\n context: 'Called when adjusting flag settings.',\n },\n io: {\n input: UpdateFlagInput,\n output: FeatureFlagModel,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag ID is invalid',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Delete a feature flag.\n */\nexport const DeleteFlagContract = defineCommand({\n meta: {\n name: 'flag.delete',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'delete'],\n description: 'Delete a feature flag.',\n goal: 'Remove a feature flag and all its rules.',\n context: 'Called when a flag is no longer needed.',\n },\n io: {\n input: DeleteFlagInput,\n output: SuccessOutput,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag ID is invalid',\n },\n FLAG_HAS_ACTIVE_EXPERIMENT: {\n description: 'Flag has an active experiment',\n http: 409,\n gqlCode: 'FLAG_HAS_ACTIVE_EXPERIMENT',\n when: 'Cannot delete flag with running experiment',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Toggle a feature flag status.\n */\nexport const ToggleFlagContract = defineCommand({\n meta: {\n name: 'flag.toggle',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'toggle'],\n description: 'Toggle a feature flag status.',\n goal: 'Quickly enable or disable a feature.',\n context: 'Called when turning a feature on or off.',\n },\n io: {\n input: ToggleFlagInput,\n output: FeatureFlagModel,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag ID is invalid',\n },\n INVALID_STATUS: {\n description: 'Invalid status value',\n http: 400,\n gqlCode: 'INVALID_STATUS',\n when: 'Status must be OFF, ON, or GRADUAL',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Get a feature flag by key.\n */\nexport const GetFlagContract = defineQuery({\n meta: {\n name: 'flag.get',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'get'],\n description: 'Get a feature flag by key.',\n goal: 'Retrieve flag configuration.',\n context: 'Called to inspect flag details.',\n },\n io: {\n input: GetFlagInput,\n output: FeatureFlagModel,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag key is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n\n/**\n * List feature flags.\n */\nexport const ListFlagsContract = defineQuery({\n meta: {\n name: 'flag.list',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'list'],\n description: 'List all feature flags.',\n goal: 'View all configured flags.',\n context: 'Admin dashboard.',\n },\n io: {\n input: ListFlagsInput,\n output: ListFlagsOutput,\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Evaluate a feature flag.\n */\nexport const EvaluateFlagContract = defineQuery({\n meta: {\n name: 'flag.evaluate',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'evaluate'],\n description: 'Evaluate a feature flag for a given context.',\n goal: 'Determine if a feature should be enabled.',\n context: 'Called at runtime to check feature availability.',\n },\n io: {\n input: EvaluateFlagInput,\n output: EvaluationResultModel,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag key is invalid',\n },\n },\n },\n policy: {\n auth: 'anonymous',\n },\n});\n\n/**\n * Create a targeting rule.\n */\nexport const CreateRuleContract = defineCommand({\n meta: {\n name: 'flag.rule.create',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'rule', 'create'],\n description: 'Create a targeting rule for a flag.',\n goal: 'Add conditional targeting to a flag.',\n context: 'Called when setting up targeting.',\n },\n io: {\n input: CreateRuleInput,\n output: TargetingRuleModel,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag ID is invalid',\n },\n INVALID_OPERATOR: {\n description: 'Invalid operator',\n http: 400,\n gqlCode: 'INVALID_OPERATOR',\n when: 'Operator is not supported',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Delete a targeting rule.\n */\nexport const DeleteRuleContract = defineCommand({\n meta: {\n name: 'flag.rule.delete',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'rule', 'delete'],\n description: 'Delete a targeting rule.',\n goal: 'Remove a targeting rule from a flag.',\n context: 'Called when removing targeting conditions.',\n },\n io: {\n input: DeleteRuleInput,\n output: SuccessOutput,\n errors: {\n RULE_NOT_FOUND: {\n description: 'Rule does not exist',\n http: 404,\n gqlCode: 'RULE_NOT_FOUND',\n when: 'Rule ID is invalid',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Create an experiment.\n */\nexport const CreateExperimentContract = defineCommand({\n meta: {\n name: 'experiment.create',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'experiment', 'create'],\n description: 'Create an A/B test experiment.',\n goal: 'Set up an experiment with variants.',\n context: 'Called when setting up A/B testing.',\n },\n io: {\n input: CreateExperimentInput,\n output: ExperimentModel,\n errors: {\n FLAG_NOT_FOUND: {\n description: 'Flag does not exist',\n http: 404,\n gqlCode: 'FLAG_NOT_FOUND',\n when: 'Flag ID is invalid',\n },\n EXPERIMENT_KEY_EXISTS: {\n description: 'Experiment key already exists',\n http: 409,\n gqlCode: 'EXPERIMENT_KEY_EXISTS',\n when: 'An experiment with this key already exists',\n },\n INVALID_VARIANTS: {\n description: 'Invalid variant configuration',\n http: 400,\n gqlCode: 'INVALID_VARIANTS',\n when: 'Variant percentages must sum to 100',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Start an experiment.\n */\nexport const StartExperimentContract = defineCommand({\n meta: {\n name: 'experiment.start',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'experiment', 'start'],\n description: 'Start an experiment.',\n goal: 'Begin collecting data for an experiment.',\n context: 'Called when ready to run an A/B test.',\n },\n io: {\n input: StartExperimentInput,\n output: ExperimentModel,\n errors: {\n EXPERIMENT_NOT_FOUND: {\n description: 'Experiment does not exist',\n http: 404,\n gqlCode: 'EXPERIMENT_NOT_FOUND',\n when: 'Experiment ID is invalid',\n },\n EXPERIMENT_ALREADY_RUNNING: {\n description: 'Experiment is already running',\n http: 409,\n gqlCode: 'EXPERIMENT_ALREADY_RUNNING',\n when: 'Cannot start an experiment that is already running',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Stop an experiment.\n */\nexport const StopExperimentContract = defineCommand({\n meta: {\n name: 'experiment.stop',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'experiment', 'stop'],\n description: 'Stop an experiment.',\n goal: 'End an experiment and optionally declare a winner.',\n context: 'Called when concluding an A/B test.',\n },\n io: {\n input: StopExperimentInput,\n output: ExperimentModel,\n errors: {\n EXPERIMENT_NOT_FOUND: {\n description: 'Experiment does not exist',\n http: 404,\n gqlCode: 'EXPERIMENT_NOT_FOUND',\n when: 'Experiment ID is invalid',\n },\n EXPERIMENT_NOT_RUNNING: {\n description: 'Experiment is not running',\n http: 409,\n gqlCode: 'EXPERIMENT_NOT_RUNNING',\n when: 'Cannot stop an experiment that is not running',\n },\n },\n },\n policy: {\n auth: 'admin',\n },\n});\n\n/**\n * Get an experiment.\n */\nexport const GetExperimentContract = defineQuery({\n meta: {\n name: 'experiment.get',\n version: 1,\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['feature-flags', 'experiment', 'get'],\n description: 'Get experiment details.',\n goal: 'View experiment configuration and results.',\n context: 'Called to inspect experiment status.',\n },\n io: {\n input: GetExperimentInput,\n output: ExperimentModel,\n errors: {\n EXPERIMENT_NOT_FOUND: {\n description: 'Experiment does not exist',\n http: 404,\n gqlCode: 'EXPERIMENT_NOT_FOUND',\n when: 'Experiment ID is invalid',\n },\n },\n },\n policy: {\n auth: 'user',\n },\n});\n"],"mappings":"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"}
@@ -73,4 +73,5 @@ if (result.enabled) {
73
73
  `
74
74
  }]);
75
75
 
76
- //#endregion
76
+ //#endregion
77
+ //# sourceMappingURL=feature-flags.docblock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-flags.docblock.js","names":[],"sources":["../../src/docs/feature-flags.docblock.ts"],"sourcesContent":["import type { DocBlock } from '@lssm/lib.contracts/docs';\nimport { registerDocBlocks } from '@lssm/lib.contracts/docs';\n\nconst featureFlagsDocBlocks: DocBlock[] = [\n {\n id: 'docs.feature-flags.overview',\n title: 'Feature Flags & Experiments',\n summary:\n 'Reusable, spec-first feature flag and experiment module with targeting, gradual rollout, multivariate variants, and evaluation logging.',\n kind: 'reference',\n visibility: 'public',\n route: '/docs/feature-flags/overview',\n tags: ['feature-flags', 'experiments', 'progressive-delivery'],\n body: `## What this module provides\n\n- **Entities**: FeatureFlag, FlagTargetingRule, Experiment, ExperimentAssignment, FlagEvaluation.\n- **Contracts**: create/update/delete/toggle/list/get flags; create/delete rules; evaluate flags; create/start/stop/get experiments.\n- **Events**: flag.created/updated/deleted/toggled, rule.created/deleted, experiment.created/started/stopped, flag.evaluated, experiment.variant_assigned.\n- **Evaluation Engine**: Deterministic evaluator with gradual rollout, rule priority, audience filters, and experiment bucketing.\n\n## How to use\n\n1) Compose schema\n - Add \\`featureFlagsSchemaContribution\\` to your module composition.\n\n2) Register contracts/events\n - Import exports from \\`@lssm/lib.feature-flags\\` into your spec registry.\n\n3) Evaluate at runtime\n - Instantiate \\`FlagEvaluator\\` with a repository implementation and optional logger.\n - Evaluate with context attributes (userId, orgId, plan, segment, sessionId, attributes).\n\n4) Wire observability\n - Emit audit trail on config changes; emit \\`flag.evaluated\\` for analytics.\n\n## Usage example\n\n${'```'}ts\nimport {\n FlagEvaluator,\n InMemoryFlagRepository,\n} from '@lssm/lib.feature-flags';\n\nconst repo = new InMemoryFlagRepository();\nrepo.addFlag({\n id: 'flag-1',\n key: 'new_dashboard',\n status: 'GRADUAL',\n defaultValue: false,\n});\n\nconst evaluator = new FlagEvaluator({ repository: repo });\nconst result = await evaluator.evaluate('new_dashboard', {\n userId: 'user-123',\n orgId: 'org-456',\n plan: 'pro',\n});\n\nif (result.enabled) {\n // serve the new dashboard\n}\n${'```'},\n\n## Guardrails\n\n- Keep flag keys stable and human-readable; avoid PII in context.\n- Ensure experiments’ variant percentages sum to 100; default flag status to OFF.\n- Use org-scoped flags for multi-tenant isolation.\n- Log evaluations only when needed to control volume; prefer sampling for noisy paths.\n`,\n },\n];\n\nregisterDocBlocks(featureFlagsDocBlocks);\n"],"mappings":";;;;AAyEA,kBAtE0C,CACxC;CACE,IAAI;CACJ,OAAO;CACP,SACE;CACF,MAAM;CACN,YAAY;CACZ,OAAO;CACP,MAAM;EAAC;EAAiB;EAAe;EAAuB;CAC9D,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDP,CACF,CAEuC"}
@@ -197,4 +197,5 @@ declare const featureFlagEntities: (_lssm_lib_schema413.EntitySpec<{
197
197
  */
198
198
  declare const featureFlagsSchemaContribution: ModuleSchemaContribution;
199
199
  //#endregion
200
- export { ExperimentAssignmentEntity, ExperimentEntity, ExperimentStatusEnum, FeatureFlagEntity, FlagEvaluationEntity, FlagStatusEnum, FlagTargetingRuleEntity, RuleOperatorEnum, featureFlagEntities, featureFlagsSchemaContribution };
200
+ export { ExperimentAssignmentEntity, ExperimentEntity, ExperimentStatusEnum, FeatureFlagEntity, FlagEvaluationEntity, FlagStatusEnum, FlagTargetingRuleEntity, RuleOperatorEnum, featureFlagEntities, featureFlagsSchemaContribution };
201
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/entities/index.ts"],"sourcesContent":[],"mappings":";;;;;;;AAMa,cAAA,cAKX,EAAA,mBAAA,CALyB,aAKzB;AAKF;AAsBA;AAUA;AA4DE,cA5FW,gBA4FX,EA3EA,mBAAA,CAjB2B,aA4F3B;;;;cAtEW,sBAKX,mBAAA,CAL+B;;;;cAUpB,uCAAiB;MA4D5B,mBAAA,CAAA;;;;;;iDA5D4B;EAAA,KAAA,uCAAA;EAiEjB,IAAA,uCAyDX;EAAA,QAAA,uCAAA;;;;;;;;;;cAzDW,6CAAuB;MAyDlC,mBAAA,CAAA;;;iDAzDkC;EAAA,OAAA,uCAAA;EA8DvB,SAAA,uCA2FX;EAAA,QAAA,qCAAA;;;;;;;;;;;;cA3FW,sCAAgB;MA2F3B,mBAAA,CAAA;;;;;;;;;oBA3F2B,uCAAA;EAAA,cAAA,uCAAA;EAgGhB,gBAAA,uCAuCX;EAAA,cAAA,uCAAA;;;;;;;;;sDAvCqC;CAAA,CAAA;AA4CvC;;;cA5Ca,gDAA0B;MAuCrC,mBAAA,CAAA;;;;;;;;;;;AA+DF;;cA1Da,0CAAoB;MAqD/B,mBAAA,CAAA;;;;;;;;;;;;;;;;cAKW,0CAAmB;MAM/B,mBAAA,CAAA;;;;;;;;;;;;;;;;MAN+B,mBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWnB,MAAA,uCAAgC;;;;;;;;;;;;;;;;;;;;;cAAhC,gCAAgC"}
@@ -1,11 +1,10 @@
1
- import { defineEntity, defineEntityEnum, field, index } from "../schema/dist/entity/defineEntity.js";
2
- import "../schema/dist/index.js";
1
+ import { L5, Z5, _5, b5 } from "../schema/dist/index.js";
3
2
 
4
3
  //#region src/entities/index.ts
5
4
  /**
6
5
  * Feature flag status enum.
7
6
  */
8
- const FlagStatusEnum = defineEntityEnum({
7
+ const FlagStatusEnum = Z5({
9
8
  name: "FlagStatus",
10
9
  values: [
11
10
  "OFF",
@@ -18,7 +17,7 @@ const FlagStatusEnum = defineEntityEnum({
18
17
  /**
19
18
  * Targeting rule operator enum.
20
19
  */
21
- const RuleOperatorEnum = defineEntityEnum({
20
+ const RuleOperatorEnum = Z5({
22
21
  name: "RuleOperator",
23
22
  values: [
24
23
  "EQ",
@@ -39,7 +38,7 @@ const RuleOperatorEnum = defineEntityEnum({
39
38
  /**
40
39
  * Experiment status enum.
41
40
  */
42
- const ExperimentStatusEnum = defineEntityEnum({
41
+ const ExperimentStatusEnum = Z5({
43
42
  name: "ExperimentStatus",
44
43
  values: [
45
44
  "DRAFT",
@@ -54,248 +53,248 @@ const ExperimentStatusEnum = defineEntityEnum({
54
53
  /**
55
54
  * FeatureFlag entity - defines a feature flag.
56
55
  */
57
- const FeatureFlagEntity = defineEntity({
56
+ const FeatureFlagEntity = L5({
58
57
  name: "FeatureFlag",
59
58
  description: "A feature flag for controlling feature availability.",
60
59
  schema: "lssm_feature_flags",
61
60
  map: "feature_flag",
62
61
  fields: {
63
- id: field.id({ description: "Unique flag identifier" }),
64
- key: field.string({
62
+ id: _5.id({ description: "Unique flag identifier" }),
63
+ key: _5.string({
65
64
  isUnique: true,
66
65
  description: "Flag key (e.g., new_dashboard)"
67
66
  }),
68
- name: field.string({ description: "Human-readable name" }),
69
- description: field.string({
67
+ name: _5.string({ description: "Human-readable name" }),
68
+ description: _5.string({
70
69
  isOptional: true,
71
70
  description: "Description of the flag"
72
71
  }),
73
- status: field.enum("FlagStatus", {
72
+ status: _5.enum("FlagStatus", {
74
73
  default: "OFF",
75
74
  description: "Flag status"
76
75
  }),
77
- defaultValue: field.boolean({
76
+ defaultValue: _5.boolean({
78
77
  default: false,
79
78
  description: "Default value when no rules match"
80
79
  }),
81
- variants: field.json({
80
+ variants: _5.json({
82
81
  isOptional: true,
83
82
  description: "Variant definitions for multivariate flags"
84
83
  }),
85
- orgId: field.string({
84
+ orgId: _5.string({
86
85
  isOptional: true,
87
86
  description: "Organization scope (null = global)"
88
87
  }),
89
- tags: field.json({
88
+ tags: _5.json({
90
89
  isOptional: true,
91
90
  description: "Tags for categorization"
92
91
  }),
93
- metadata: field.json({
92
+ metadata: _5.json({
94
93
  isOptional: true,
95
94
  description: "Additional metadata"
96
95
  }),
97
- createdAt: field.createdAt(),
98
- updatedAt: field.updatedAt(),
99
- targetingRules: field.hasMany("FlagTargetingRule"),
100
- experiments: field.hasMany("Experiment"),
101
- evaluations: field.hasMany("FlagEvaluation")
96
+ createdAt: _5.createdAt(),
97
+ updatedAt: _5.updatedAt(),
98
+ targetingRules: _5.hasMany("FlagTargetingRule"),
99
+ experiments: _5.hasMany("Experiment"),
100
+ evaluations: _5.hasMany("FlagEvaluation")
102
101
  },
103
- indexes: [index.on(["orgId", "key"]), index.on(["status"])],
102
+ indexes: [b5.on(["orgId", "key"]), b5.on(["status"])],
104
103
  enums: [FlagStatusEnum]
105
104
  });
106
105
  /**
107
106
  * FlagTargetingRule entity - conditions for targeting.
108
107
  */
109
- const FlagTargetingRuleEntity = defineEntity({
108
+ const FlagTargetingRuleEntity = L5({
110
109
  name: "FlagTargetingRule",
111
110
  description: "A targeting rule for conditional flag evaluation.",
112
111
  schema: "lssm_feature_flags",
113
112
  map: "flag_targeting_rule",
114
113
  fields: {
115
- id: field.id({ description: "Unique rule identifier" }),
116
- flagId: field.foreignKey({ description: "Parent feature flag" }),
117
- name: field.string({
114
+ id: _5.id({ description: "Unique rule identifier" }),
115
+ flagId: _5.foreignKey({ description: "Parent feature flag" }),
116
+ name: _5.string({
118
117
  isOptional: true,
119
118
  description: "Rule name for debugging"
120
119
  }),
121
- priority: field.int({
120
+ priority: _5.int({
122
121
  default: 0,
123
122
  description: "Rule priority (lower = higher priority)"
124
123
  }),
125
- enabled: field.boolean({
124
+ enabled: _5.boolean({
126
125
  default: true,
127
126
  description: "Whether rule is active"
128
127
  }),
129
- attribute: field.string({ description: "Target attribute (userId, orgId, plan, segment, etc.)" }),
130
- operator: field.enum("RuleOperator", { description: "Comparison operator" }),
131
- value: field.json({ description: "Target value(s)" }),
132
- rolloutPercentage: field.int({
128
+ attribute: _5.string({ description: "Target attribute (userId, orgId, plan, segment, etc.)" }),
129
+ operator: _5.enum("RuleOperator", { description: "Comparison operator" }),
130
+ value: _5.json({ description: "Target value(s)" }),
131
+ rolloutPercentage: _5.int({
133
132
  isOptional: true,
134
133
  description: "Percentage for gradual rollout (0-100)"
135
134
  }),
136
- serveValue: field.boolean({
135
+ serveValue: _5.boolean({
137
136
  isOptional: true,
138
137
  description: "Boolean value to serve"
139
138
  }),
140
- serveVariant: field.string({
139
+ serveVariant: _5.string({
141
140
  isOptional: true,
142
141
  description: "Variant key to serve (for multivariate)"
143
142
  }),
144
- createdAt: field.createdAt(),
145
- updatedAt: field.updatedAt(),
146
- flag: field.belongsTo("FeatureFlag", ["flagId"], ["id"], { onDelete: "Cascade" })
143
+ createdAt: _5.createdAt(),
144
+ updatedAt: _5.updatedAt(),
145
+ flag: _5.belongsTo("FeatureFlag", ["flagId"], ["id"], { onDelete: "Cascade" })
147
146
  },
148
- indexes: [index.on(["flagId", "priority"]), index.on(["attribute"])],
147
+ indexes: [b5.on(["flagId", "priority"]), b5.on(["attribute"])],
149
148
  enums: [RuleOperatorEnum]
150
149
  });
151
150
  /**
152
151
  * Experiment entity - A/B test configuration.
153
152
  */
154
- const ExperimentEntity = defineEntity({
153
+ const ExperimentEntity = L5({
155
154
  name: "Experiment",
156
155
  description: "An A/B test experiment.",
157
156
  schema: "lssm_feature_flags",
158
157
  map: "experiment",
159
158
  fields: {
160
- id: field.id({ description: "Unique experiment identifier" }),
161
- key: field.string({
159
+ id: _5.id({ description: "Unique experiment identifier" }),
160
+ key: _5.string({
162
161
  isUnique: true,
163
162
  description: "Experiment key"
164
163
  }),
165
- name: field.string({ description: "Human-readable name" }),
166
- description: field.string({
164
+ name: _5.string({ description: "Human-readable name" }),
165
+ description: _5.string({
167
166
  isOptional: true,
168
167
  description: "Experiment description"
169
168
  }),
170
- hypothesis: field.string({
169
+ hypothesis: _5.string({
171
170
  isOptional: true,
172
171
  description: "Experiment hypothesis"
173
172
  }),
174
- flagId: field.foreignKey({ description: "Associated feature flag" }),
175
- status: field.enum("ExperimentStatus", {
173
+ flagId: _5.foreignKey({ description: "Associated feature flag" }),
174
+ status: _5.enum("ExperimentStatus", {
176
175
  default: "DRAFT",
177
176
  description: "Experiment status"
178
177
  }),
179
- variants: field.json({ description: "Variant definitions with split ratios" }),
180
- metrics: field.json({
178
+ variants: _5.json({ description: "Variant definitions with split ratios" }),
179
+ metrics: _5.json({
181
180
  isOptional: true,
182
181
  description: "Metrics to track"
183
182
  }),
184
- audiencePercentage: field.int({
183
+ audiencePercentage: _5.int({
185
184
  default: 100,
186
185
  description: "Percentage of audience to include"
187
186
  }),
188
- audienceFilter: field.json({
187
+ audienceFilter: _5.json({
189
188
  isOptional: true,
190
189
  description: "Audience filter criteria"
191
190
  }),
192
- scheduledStartAt: field.dateTime({
191
+ scheduledStartAt: _5.dateTime({
193
192
  isOptional: true,
194
193
  description: "Scheduled start time"
195
194
  }),
196
- scheduledEndAt: field.dateTime({
195
+ scheduledEndAt: _5.dateTime({
197
196
  isOptional: true,
198
197
  description: "Scheduled end time"
199
198
  }),
200
- startedAt: field.dateTime({
199
+ startedAt: _5.dateTime({
201
200
  isOptional: true,
202
201
  description: "Actual start time"
203
202
  }),
204
- endedAt: field.dateTime({
203
+ endedAt: _5.dateTime({
205
204
  isOptional: true,
206
205
  description: "Actual end time"
207
206
  }),
208
- winningVariant: field.string({
207
+ winningVariant: _5.string({
209
208
  isOptional: true,
210
209
  description: "Declared winning variant"
211
210
  }),
212
- results: field.json({
211
+ results: _5.json({
213
212
  isOptional: true,
214
213
  description: "Experiment results summary"
215
214
  }),
216
- orgId: field.string({
215
+ orgId: _5.string({
217
216
  isOptional: true,
218
217
  description: "Organization scope"
219
218
  }),
220
- createdAt: field.createdAt(),
221
- updatedAt: field.updatedAt(),
222
- flag: field.belongsTo("FeatureFlag", ["flagId"], ["id"], { onDelete: "Cascade" }),
223
- assignments: field.hasMany("ExperimentAssignment")
219
+ createdAt: _5.createdAt(),
220
+ updatedAt: _5.updatedAt(),
221
+ flag: _5.belongsTo("FeatureFlag", ["flagId"], ["id"], { onDelete: "Cascade" }),
222
+ assignments: _5.hasMany("ExperimentAssignment")
224
223
  },
225
224
  indexes: [
226
- index.on(["status"]),
227
- index.on(["orgId", "status"]),
228
- index.on(["flagId"])
225
+ b5.on(["status"]),
226
+ b5.on(["orgId", "status"]),
227
+ b5.on(["flagId"])
229
228
  ],
230
229
  enums: [ExperimentStatusEnum]
231
230
  });
232
231
  /**
233
232
  * ExperimentAssignment entity - tracks which variant a subject is assigned to.
234
233
  */
235
- const ExperimentAssignmentEntity = defineEntity({
234
+ const ExperimentAssignmentEntity = L5({
236
235
  name: "ExperimentAssignment",
237
236
  description: "Tracks experiment variant assignments.",
238
237
  schema: "lssm_feature_flags",
239
238
  map: "experiment_assignment",
240
239
  fields: {
241
- id: field.id({ description: "Unique assignment identifier" }),
242
- experimentId: field.foreignKey({ description: "Parent experiment" }),
243
- subjectType: field.string({ description: "Subject type (user, org, session)" }),
244
- subjectId: field.string({ description: "Subject identifier" }),
245
- variant: field.string({ description: "Assigned variant key" }),
246
- bucket: field.int({ description: "Hash bucket (0-99)" }),
247
- context: field.json({
240
+ id: _5.id({ description: "Unique assignment identifier" }),
241
+ experimentId: _5.foreignKey({ description: "Parent experiment" }),
242
+ subjectType: _5.string({ description: "Subject type (user, org, session)" }),
243
+ subjectId: _5.string({ description: "Subject identifier" }),
244
+ variant: _5.string({ description: "Assigned variant key" }),
245
+ bucket: _5.int({ description: "Hash bucket (0-99)" }),
246
+ context: _5.json({
248
247
  isOptional: true,
249
248
  description: "Context at assignment time"
250
249
  }),
251
- assignedAt: field.dateTime({ description: "Assignment timestamp" }),
252
- experiment: field.belongsTo("Experiment", ["experimentId"], ["id"], { onDelete: "Cascade" })
250
+ assignedAt: _5.dateTime({ description: "Assignment timestamp" }),
251
+ experiment: _5.belongsTo("Experiment", ["experimentId"], ["id"], { onDelete: "Cascade" })
253
252
  },
254
- indexes: [index.unique([
253
+ indexes: [b5.unique([
255
254
  "experimentId",
256
255
  "subjectType",
257
256
  "subjectId"
258
- ], { name: "experiment_assignment_unique" }), index.on(["subjectType", "subjectId"])]
257
+ ], { name: "experiment_assignment_unique" }), b5.on(["subjectType", "subjectId"])]
259
258
  });
260
259
  /**
261
260
  * FlagEvaluation entity - evaluation log for analytics.
262
261
  */
263
- const FlagEvaluationEntity = defineEntity({
262
+ const FlagEvaluationEntity = L5({
264
263
  name: "FlagEvaluation",
265
264
  description: "Log of flag evaluations for debugging and analytics.",
266
265
  schema: "lssm_feature_flags",
267
266
  map: "flag_evaluation",
268
267
  fields: {
269
- id: field.id({ description: "Unique evaluation identifier" }),
270
- flagId: field.foreignKey({ description: "Evaluated flag" }),
271
- flagKey: field.string({ description: "Flag key (denormalized for queries)" }),
272
- subjectType: field.string({ description: "Subject type (user, org, anonymous)" }),
273
- subjectId: field.string({ description: "Subject identifier" }),
274
- result: field.boolean({ description: "Evaluation result" }),
275
- variant: field.string({
268
+ id: _5.id({ description: "Unique evaluation identifier" }),
269
+ flagId: _5.foreignKey({ description: "Evaluated flag" }),
270
+ flagKey: _5.string({ description: "Flag key (denormalized for queries)" }),
271
+ subjectType: _5.string({ description: "Subject type (user, org, anonymous)" }),
272
+ subjectId: _5.string({ description: "Subject identifier" }),
273
+ result: _5.boolean({ description: "Evaluation result" }),
274
+ variant: _5.string({
276
275
  isOptional: true,
277
276
  description: "Served variant (for multivariate)"
278
277
  }),
279
- matchedRuleId: field.string({
278
+ matchedRuleId: _5.string({
280
279
  isOptional: true,
281
280
  description: "Rule that matched (if any)"
282
281
  }),
283
- reason: field.string({ description: "Evaluation reason (default, rule, experiment, etc.)" }),
284
- context: field.json({
282
+ reason: _5.string({ description: "Evaluation reason (default, rule, experiment, etc.)" }),
283
+ context: _5.json({
285
284
  isOptional: true,
286
285
  description: "Evaluation context"
287
286
  }),
288
- evaluatedAt: field.dateTime({ description: "Evaluation timestamp" }),
289
- flag: field.belongsTo("FeatureFlag", ["flagId"], ["id"], { onDelete: "Cascade" })
287
+ evaluatedAt: _5.dateTime({ description: "Evaluation timestamp" }),
288
+ flag: _5.belongsTo("FeatureFlag", ["flagId"], ["id"], { onDelete: "Cascade" })
290
289
  },
291
290
  indexes: [
292
- index.on(["flagKey", "evaluatedAt"]),
293
- index.on([
291
+ b5.on(["flagKey", "evaluatedAt"]),
292
+ b5.on([
294
293
  "subjectType",
295
294
  "subjectId",
296
295
  "evaluatedAt"
297
296
  ]),
298
- index.on(["flagId", "evaluatedAt"])
297
+ b5.on(["flagId", "evaluatedAt"])
299
298
  ]
300
299
  });
301
300
  /**
@@ -322,4 +321,5 @@ const featureFlagsSchemaContribution = {
322
321
  };
323
322
 
324
323
  //#endregion
325
- export { ExperimentAssignmentEntity, ExperimentEntity, ExperimentStatusEnum, FeatureFlagEntity, FlagEvaluationEntity, FlagStatusEnum, FlagTargetingRuleEntity, RuleOperatorEnum, featureFlagEntities, featureFlagsSchemaContribution };
324
+ export { ExperimentAssignmentEntity, ExperimentEntity, ExperimentStatusEnum, FeatureFlagEntity, FlagEvaluationEntity, FlagStatusEnum, FlagTargetingRuleEntity, RuleOperatorEnum, featureFlagEntities, featureFlagsSchemaContribution };
325
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["defineEntityEnum","defineEntity","field","index","featureFlagsSchemaContribution: ModuleSchemaContribution"],"sources":["../../src/entities/index.ts"],"sourcesContent":["import { defineEntity, defineEntityEnum, field, index } from '@lssm/lib.schema';\nimport type { ModuleSchemaContribution } from '@lssm/lib.schema';\n\n/**\n * Feature flag status enum.\n */\nexport const FlagStatusEnum = defineEntityEnum({\n name: 'FlagStatus',\n values: ['OFF', 'ON', 'GRADUAL'] as const,\n schema: 'lssm_feature_flags',\n description: 'Status of a feature flag.',\n});\n\n/**\n * Targeting rule operator enum.\n */\nexport const RuleOperatorEnum = defineEntityEnum({\n name: 'RuleOperator',\n values: [\n 'EQ',\n 'NEQ',\n 'IN',\n 'NIN',\n 'CONTAINS',\n 'NOT_CONTAINS',\n 'GT',\n 'GTE',\n 'LT',\n 'LTE',\n 'PERCENTAGE',\n ] as const,\n schema: 'lssm_feature_flags',\n description: 'Operator for targeting rule conditions.',\n});\n\n/**\n * Experiment status enum.\n */\nexport const ExperimentStatusEnum = defineEntityEnum({\n name: 'ExperimentStatus',\n values: ['DRAFT', 'RUNNING', 'PAUSED', 'COMPLETED', 'CANCELLED'] as const,\n schema: 'lssm_feature_flags',\n description: 'Status of an experiment.',\n});\n\n/**\n * FeatureFlag entity - defines a feature flag.\n */\nexport const FeatureFlagEntity = defineEntity({\n name: 'FeatureFlag',\n description: 'A feature flag for controlling feature availability.',\n schema: 'lssm_feature_flags',\n map: 'feature_flag',\n fields: {\n id: field.id({ description: 'Unique flag identifier' }),\n key: field.string({\n isUnique: true,\n description: 'Flag key (e.g., new_dashboard)',\n }),\n name: field.string({ description: 'Human-readable name' }),\n description: field.string({\n isOptional: true,\n description: 'Description of the flag',\n }),\n\n // Status and default value\n status: field.enum('FlagStatus', {\n default: 'OFF',\n description: 'Flag status',\n }),\n defaultValue: field.boolean({\n default: false,\n description: 'Default value when no rules match',\n }),\n\n // Multivariate support\n variants: field.json({\n isOptional: true,\n description: 'Variant definitions for multivariate flags',\n }),\n\n // Scope\n orgId: field.string({\n isOptional: true,\n description: 'Organization scope (null = global)',\n }),\n\n // Metadata\n tags: field.json({\n isOptional: true,\n description: 'Tags for categorization',\n }),\n metadata: field.json({\n isOptional: true,\n description: 'Additional metadata',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n targetingRules: field.hasMany('FlagTargetingRule'),\n experiments: field.hasMany('Experiment'),\n evaluations: field.hasMany('FlagEvaluation'),\n },\n indexes: [index.on(['orgId', 'key']), index.on(['status'])],\n enums: [FlagStatusEnum],\n});\n\n/**\n * FlagTargetingRule entity - conditions for targeting.\n */\nexport const FlagTargetingRuleEntity = defineEntity({\n name: 'FlagTargetingRule',\n description: 'A targeting rule for conditional flag evaluation.',\n schema: 'lssm_feature_flags',\n map: 'flag_targeting_rule',\n fields: {\n id: field.id({ description: 'Unique rule identifier' }),\n flagId: field.foreignKey({ description: 'Parent feature flag' }),\n\n // Rule definition\n name: field.string({\n isOptional: true,\n description: 'Rule name for debugging',\n }),\n priority: field.int({\n default: 0,\n description: 'Rule priority (lower = higher priority)',\n }),\n enabled: field.boolean({\n default: true,\n description: 'Whether rule is active',\n }),\n\n // Condition\n attribute: field.string({\n description: 'Target attribute (userId, orgId, plan, segment, etc.)',\n }),\n operator: field.enum('RuleOperator', {\n description: 'Comparison operator',\n }),\n value: field.json({ description: 'Target value(s)' }),\n\n // Result\n rolloutPercentage: field.int({\n isOptional: true,\n description: 'Percentage for gradual rollout (0-100)',\n }),\n serveValue: field.boolean({\n isOptional: true,\n description: 'Boolean value to serve',\n }),\n serveVariant: field.string({\n isOptional: true,\n description: 'Variant key to serve (for multivariate)',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n flag: field.belongsTo('FeatureFlag', ['flagId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [index.on(['flagId', 'priority']), index.on(['attribute'])],\n enums: [RuleOperatorEnum],\n});\n\n/**\n * Experiment entity - A/B test configuration.\n */\nexport const ExperimentEntity = defineEntity({\n name: 'Experiment',\n description: 'An A/B test experiment.',\n schema: 'lssm_feature_flags',\n map: 'experiment',\n fields: {\n id: field.id({ description: 'Unique experiment identifier' }),\n key: field.string({ isUnique: true, description: 'Experiment key' }),\n name: field.string({ description: 'Human-readable name' }),\n description: field.string({\n isOptional: true,\n description: 'Experiment description',\n }),\n hypothesis: field.string({\n isOptional: true,\n description: 'Experiment hypothesis',\n }),\n\n // Associated flag\n flagId: field.foreignKey({ description: 'Associated feature flag' }),\n\n // Configuration\n status: field.enum('ExperimentStatus', {\n default: 'DRAFT',\n description: 'Experiment status',\n }),\n variants: field.json({\n description: 'Variant definitions with split ratios',\n }),\n metrics: field.json({ isOptional: true, description: 'Metrics to track' }),\n\n // Targeting\n audiencePercentage: field.int({\n default: 100,\n description: 'Percentage of audience to include',\n }),\n audienceFilter: field.json({\n isOptional: true,\n description: 'Audience filter criteria',\n }),\n\n // Timeline\n scheduledStartAt: field.dateTime({\n isOptional: true,\n description: 'Scheduled start time',\n }),\n scheduledEndAt: field.dateTime({\n isOptional: true,\n description: 'Scheduled end time',\n }),\n startedAt: field.dateTime({\n isOptional: true,\n description: 'Actual start time',\n }),\n endedAt: field.dateTime({\n isOptional: true,\n description: 'Actual end time',\n }),\n\n // Results\n winningVariant: field.string({\n isOptional: true,\n description: 'Declared winning variant',\n }),\n results: field.json({\n isOptional: true,\n description: 'Experiment results summary',\n }),\n\n // Scope\n orgId: field.string({\n isOptional: true,\n description: 'Organization scope',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n flag: field.belongsTo('FeatureFlag', ['flagId'], ['id'], {\n onDelete: 'Cascade',\n }),\n assignments: field.hasMany('ExperimentAssignment'),\n },\n indexes: [\n index.on(['status']),\n index.on(['orgId', 'status']),\n index.on(['flagId']),\n ],\n enums: [ExperimentStatusEnum],\n});\n\n/**\n * ExperimentAssignment entity - tracks which variant a subject is assigned to.\n */\nexport const ExperimentAssignmentEntity = defineEntity({\n name: 'ExperimentAssignment',\n description: 'Tracks experiment variant assignments.',\n schema: 'lssm_feature_flags',\n map: 'experiment_assignment',\n fields: {\n id: field.id({ description: 'Unique assignment identifier' }),\n experimentId: field.foreignKey({ description: 'Parent experiment' }),\n\n // Subject\n subjectType: field.string({\n description: 'Subject type (user, org, session)',\n }),\n subjectId: field.string({ description: 'Subject identifier' }),\n\n // Assignment\n variant: field.string({ description: 'Assigned variant key' }),\n bucket: field.int({ description: 'Hash bucket (0-99)' }),\n\n // Context\n context: field.json({\n isOptional: true,\n description: 'Context at assignment time',\n }),\n\n // Timestamps\n assignedAt: field.dateTime({ description: 'Assignment timestamp' }),\n\n // Relations\n experiment: field.belongsTo('Experiment', ['experimentId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [\n index.unique(['experimentId', 'subjectType', 'subjectId'], {\n name: 'experiment_assignment_unique',\n }),\n index.on(['subjectType', 'subjectId']),\n ],\n});\n\n/**\n * FlagEvaluation entity - evaluation log for analytics.\n */\nexport const FlagEvaluationEntity = defineEntity({\n name: 'FlagEvaluation',\n description: 'Log of flag evaluations for debugging and analytics.',\n schema: 'lssm_feature_flags',\n map: 'flag_evaluation',\n fields: {\n id: field.id({ description: 'Unique evaluation identifier' }),\n flagId: field.foreignKey({ description: 'Evaluated flag' }),\n flagKey: field.string({\n description: 'Flag key (denormalized for queries)',\n }),\n\n // Subject\n subjectType: field.string({\n description: 'Subject type (user, org, anonymous)',\n }),\n subjectId: field.string({ description: 'Subject identifier' }),\n\n // Result\n result: field.boolean({ description: 'Evaluation result' }),\n variant: field.string({\n isOptional: true,\n description: 'Served variant (for multivariate)',\n }),\n\n // Match info\n matchedRuleId: field.string({\n isOptional: true,\n description: 'Rule that matched (if any)',\n }),\n reason: field.string({\n description: 'Evaluation reason (default, rule, experiment, etc.)',\n }),\n\n // Context\n context: field.json({\n isOptional: true,\n description: 'Evaluation context',\n }),\n\n // Timestamps\n evaluatedAt: field.dateTime({ description: 'Evaluation timestamp' }),\n\n // Relations\n flag: field.belongsTo('FeatureFlag', ['flagId'], ['id'], {\n onDelete: 'Cascade',\n }),\n },\n indexes: [\n index.on(['flagKey', 'evaluatedAt']),\n index.on(['subjectType', 'subjectId', 'evaluatedAt']),\n index.on(['flagId', 'evaluatedAt']),\n ],\n});\n\n/**\n * All feature flag entities for schema composition.\n */\nexport const featureFlagEntities = [\n FeatureFlagEntity,\n FlagTargetingRuleEntity,\n ExperimentEntity,\n ExperimentAssignmentEntity,\n FlagEvaluationEntity,\n];\n\n/**\n * Module schema contribution for feature flags.\n */\nexport const featureFlagsSchemaContribution: ModuleSchemaContribution = {\n moduleId: '@lssm/lib.feature-flags',\n entities: featureFlagEntities,\n enums: [FlagStatusEnum, RuleOperatorEnum, ExperimentStatusEnum],\n};\n"],"mappings":"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"}
@@ -159,4 +159,5 @@ declare class InMemoryFlagRepository implements FlagRepository {
159
159
  clear(): void;
160
160
  }
161
161
  //#endregion
162
- export { EvaluationContext, EvaluationLogger, EvaluationReason, EvaluationResult, Experiment, ExperimentVariant, FeatureFlag, FlagEvaluator, FlagEvaluatorOptions, FlagRepository, InMemoryFlagRepository, RuleOperator, TargetingRule, VariantConfig, evaluateRuleCondition, getSubjectId, hashToBucket };
162
+ export { EvaluationContext, EvaluationLogger, EvaluationReason, EvaluationResult, Experiment, ExperimentVariant, FeatureFlag, FlagEvaluator, FlagEvaluatorOptions, FlagRepository, InMemoryFlagRepository, RuleOperator, TargetingRule, VariantConfig, evaluateRuleCondition, getSubjectId, hashToBucket };
163
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/evaluation/index.ts"],"sourcesContent":[],"mappings":";;AASA;AAeA;AAQA;AAYA;AASA;AAOiB,UAnDA,iBAAA,CAmDiB;EAMjB;EAQL,MAAA,CAAA,EAAA,MAAA;EASA;EAmBI,KAAA,CAAA,EAAA,MAAA;EAeA;EASA,IAAA,CAAA,EAAA,MAAA;EAwFC;EAC+B,OAAA,CAAA,EAAA,MAAA;EAAR;EACJ,SAAA,CAAA,EAAA,MAAA;EAAR;EACmB,UAAA,CAAA,EApMhC,MAoMgC,CAAA,MAAA,EAAA,OAAA,CAAA;;AAK1C,UAtMY,WAAA,CAsMZ;EAOA,EAAA,EAAA,MAAA;EAAO,GAAA,EAAA,MAAA;EAGK,MAAA,EAAA,KAAA,GAAA,IAAgB,GAAA,SAWnB;EAIG,YAAA,EAAA,OAAA;EAgBJ,QAAA,CAAA,EA1OA,aA0Oa,EAAA;;AAgBb,UAvPI,aAAA,CAuPJ;EACA,EAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAAO,OAAA,EAAA,OAAA;EAsMC,SAAA,EAAA,MAAA;EAMG,QAAA,EA/bJ,YA+bI;EAIgB,KAAA,EAAA,OAAA;EAMJ,iBAAA,CAAA,EAAA,MAAA;EAIU,UAAA,CAAA,EAAA,OAAA;EAAR,YAAA,CAAA,EAAA,MAAA;;AAII,UA1cjB,UAAA,CA0ciB;EAImB,EAAA,EAAA,MAAA;EAAR,GAAA,EAAA,MAAA;EAQxC,MAAA,EAAA,OAAA,GAAA,SAAA,GAAA,QAAA,GAAA,WAAA,GAAA,WAAA;EAUA,QAAA,EA5dO,iBA4dP,EAAA;EA9C0C,kBAAA,EAAA,MAAA;EAAc,cAAA,CAAA,EA5a1C,MA4a0C,CAAA,MAAA,EAAA,OAAA,CAAA;;UAza5C,aAAA;;;;;;UAOA,iBAAA;;;;;UAMA,gBAAA;;;UAGP;;;;KAKE,gBAAA;KASA,YAAA;;;;;iBAmBI,YAAA;;;;iBAeA,YAAA,UAAsB;;;;iBAStB,qBAAA,OACR,wBACG;UAsFM,cAAA;wCACuB,QAAQ;4BACpB,QAAQ;uCACG,QAAQ;yFAK1C;2HAOA;;UAGY,gBAAA;;;;;;;;;;;cAWH;;;UAIG,oBAAA;cACH;WACH;;;;;;;;;;;;;cAcE,aAAA;;;;uBAKU;;;;iCAWV,oBACR,QAAQ;;;;;;;;;;;;;;;;;;;;;cAsMA,sBAAA,YAAkC;;;;;gBAM/B;gCAIgB;4BAMJ;wBAIE,QAAQ;4BAIJ,QAAQ;uCAIG,QAAQ;yFAQhD;2GAUA"}
@@ -217,4 +217,5 @@ var InMemoryFlagRepository = class {
217
217
  };
218
218
 
219
219
  //#endregion
220
- export { FlagEvaluator, InMemoryFlagRepository, evaluateRuleCondition, getSubjectId, hashToBucket };
220
+ export { FlagEvaluator, InMemoryFlagRepository, evaluateRuleCondition, getSubjectId, hashToBucket };
221
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/evaluation/index.ts"],"sourcesContent":["/**\n * Feature flag evaluation engine.\n *\n * Provides deterministic evaluation of feature flags based on targeting rules\n * and experiment assignments.\n */\n\n// ============ Types ============\n\nexport interface EvaluationContext {\n /** User identifier */\n userId?: string;\n /** Organization identifier */\n orgId?: string;\n /** User's plan (free, pro, enterprise, etc.) */\n plan?: string;\n /** User segment or cohort */\n segment?: string;\n /** Session identifier for anonymous users */\n sessionId?: string;\n /** Additional custom attributes */\n attributes?: Record<string, unknown>;\n}\n\nexport interface FeatureFlag {\n id: string;\n key: string;\n status: 'OFF' | 'ON' | 'GRADUAL';\n defaultValue: boolean;\n variants?: VariantConfig[];\n}\n\nexport interface TargetingRule {\n id: string;\n priority: number;\n enabled: boolean;\n attribute: string;\n operator: RuleOperator;\n value: unknown;\n rolloutPercentage?: number;\n serveValue?: boolean;\n serveVariant?: string;\n}\n\nexport interface Experiment {\n id: string;\n key: string;\n status: 'DRAFT' | 'RUNNING' | 'PAUSED' | 'COMPLETED' | 'CANCELLED';\n variants: ExperimentVariant[];\n audiencePercentage: number;\n audienceFilter?: Record<string, unknown>;\n}\n\nexport interface VariantConfig {\n key: string;\n name: string;\n description?: string;\n weight?: number;\n}\n\nexport interface ExperimentVariant {\n key: string;\n name: string;\n percentage: number;\n}\n\nexport interface EvaluationResult {\n enabled: boolean;\n variant?: string;\n reason: EvaluationReason;\n ruleId?: string;\n experimentId?: string;\n}\n\nexport type EvaluationReason =\n | 'FLAG_OFF'\n | 'FLAG_ON'\n | 'DEFAULT_VALUE'\n | 'RULE_MATCH'\n | 'PERCENTAGE_ROLLOUT'\n | 'EXPERIMENT_VARIANT'\n | 'FLAG_NOT_FOUND';\n\nexport type RuleOperator =\n | 'EQ'\n | 'NEQ'\n | 'IN'\n | 'NIN'\n | 'CONTAINS'\n | 'NOT_CONTAINS'\n | 'GT'\n | 'GTE'\n | 'LT'\n | 'LTE'\n | 'PERCENTAGE';\n\n// ============ Hashing ============\n\n/**\n * Simple hash function for consistent bucketing.\n * Uses a deterministic algorithm so the same input always produces the same bucket.\n */\nexport function hashToBucket(value: string, seed = ''): number {\n const input = `${seed}:${value}`;\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n // Return a number between 0 and 99\n return Math.abs(hash % 100);\n}\n\n/**\n * Get subject identifier from context for consistent hashing.\n */\nexport function getSubjectId(context: EvaluationContext): string {\n return context.userId || context.sessionId || context.orgId || 'anonymous';\n}\n\n// ============ Rule Evaluation ============\n\n/**\n * Evaluate a single targeting rule condition.\n */\nexport function evaluateRuleCondition(\n rule: TargetingRule,\n context: EvaluationContext\n): boolean {\n const attributeValue = getAttributeValue(rule.attribute, context);\n\n switch (rule.operator) {\n case 'EQ':\n return attributeValue === rule.value;\n\n case 'NEQ':\n return attributeValue !== rule.value;\n\n case 'IN':\n if (!Array.isArray(rule.value)) return false;\n return rule.value.includes(attributeValue);\n\n case 'NIN':\n if (!Array.isArray(rule.value)) return true;\n return !rule.value.includes(attributeValue);\n\n case 'CONTAINS':\n if (typeof attributeValue !== 'string' || typeof rule.value !== 'string')\n return false;\n return attributeValue.includes(rule.value);\n\n case 'NOT_CONTAINS':\n if (typeof attributeValue !== 'string' || typeof rule.value !== 'string')\n return true;\n return !attributeValue.includes(rule.value);\n\n case 'GT':\n if (typeof attributeValue !== 'number' || typeof rule.value !== 'number')\n return false;\n return attributeValue > rule.value;\n\n case 'GTE':\n if (typeof attributeValue !== 'number' || typeof rule.value !== 'number')\n return false;\n return attributeValue >= rule.value;\n\n case 'LT':\n if (typeof attributeValue !== 'number' || typeof rule.value !== 'number')\n return false;\n return attributeValue < rule.value;\n\n case 'LTE':\n if (typeof attributeValue !== 'number' || typeof rule.value !== 'number')\n return false;\n return attributeValue <= rule.value;\n\n case 'PERCENTAGE':\n // Percentage-based targeting uses consistent hashing\n return (\n hashToBucket(getSubjectId(context), rule.attribute) <\n (typeof rule.value === 'number' ? rule.value : 0)\n );\n\n default:\n return false;\n }\n}\n\n/**\n * Get attribute value from context.\n */\nfunction getAttributeValue(\n attribute: string,\n context: EvaluationContext\n): unknown {\n switch (attribute) {\n case 'userId':\n return context.userId;\n case 'orgId':\n return context.orgId;\n case 'plan':\n return context.plan;\n case 'segment':\n return context.segment;\n case 'sessionId':\n return context.sessionId;\n default:\n return context.attributes?.[attribute];\n }\n}\n\n// ============ Flag Evaluator ============\n\nexport interface FlagRepository {\n getFlag(key: string, orgId?: string): Promise<FeatureFlag | null>;\n getRules(flagId: string): Promise<TargetingRule[]>;\n getActiveExperiment(flagId: string): Promise<Experiment | null>;\n getExperimentAssignment(\n experimentId: string,\n subjectType: string,\n subjectId: string\n ): Promise<string | null>;\n saveExperimentAssignment(\n experimentId: string,\n subjectType: string,\n subjectId: string,\n variant: string,\n bucket: number\n ): Promise<void>;\n}\n\nexport interface EvaluationLogger {\n log(evaluation: {\n flagId: string;\n flagKey: string;\n subjectType: string;\n subjectId: string;\n result: boolean;\n variant?: string;\n reason: string;\n ruleId?: string;\n experimentId?: string;\n context?: EvaluationContext;\n }): void;\n}\n\nexport interface FlagEvaluatorOptions {\n repository: FlagRepository;\n logger?: EvaluationLogger;\n /** Whether to log evaluations (default: false for performance) */\n logEvaluations?: boolean;\n}\n\n/**\n * Feature flag evaluator.\n *\n * Evaluates flags based on:\n * 1. Flag status (OFF/ON/GRADUAL)\n * 2. Targeting rules (in priority order)\n * 3. Experiments (if running)\n * 4. Default value (fallback)\n */\nexport class FlagEvaluator {\n private repository: FlagRepository;\n private logger?: EvaluationLogger;\n private logEvaluations: boolean;\n\n constructor(options: FlagEvaluatorOptions) {\n this.repository = options.repository;\n this.logger = options.logger;\n this.logEvaluations = options.logEvaluations ?? false;\n }\n\n /**\n * Evaluate a feature flag.\n */\n async evaluate(\n key: string,\n context: EvaluationContext\n ): Promise<EvaluationResult> {\n const orgId = context.orgId;\n const flag = await this.repository.getFlag(key, orgId);\n\n if (!flag) {\n return this.makeResult(false, 'FLAG_NOT_FOUND');\n }\n\n // Check flag status\n if (flag.status === 'OFF') {\n return this.logAndReturn(\n flag,\n context,\n this.makeResult(false, 'FLAG_OFF')\n );\n }\n\n if (flag.status === 'ON') {\n return this.logAndReturn(flag, context, this.makeResult(true, 'FLAG_ON'));\n }\n\n // Status is GRADUAL - evaluate rules and experiments\n const rules = await this.repository.getRules(flag.id);\n\n // Sort rules by priority (lower = higher priority)\n const sortedRules = [...rules]\n .filter((r) => r.enabled)\n .sort((a, b) => a.priority - b.priority);\n\n // Evaluate rules in order\n for (const rule of sortedRules) {\n if (evaluateRuleCondition(rule, context)) {\n // Rule matched - check for percentage rollout\n if (\n rule.rolloutPercentage !== undefined &&\n rule.rolloutPercentage !== null\n ) {\n const bucket = hashToBucket(getSubjectId(context), flag.key);\n if (bucket >= rule.rolloutPercentage) {\n continue; // User not in rollout percentage, try next rule\n }\n }\n\n const enabled = rule.serveValue ?? true;\n return this.logAndReturn(\n flag,\n context,\n this.makeResult(enabled, 'RULE_MATCH', rule.serveVariant, rule.id)\n );\n }\n }\n\n // Check for active experiment\n const experiment = await this.repository.getActiveExperiment(flag.id);\n if (experiment && experiment.status === 'RUNNING') {\n const result = await this.evaluateExperiment(experiment, context);\n if (result) {\n return this.logAndReturn(flag, context, result);\n }\n }\n\n // Fall back to default value\n return this.logAndReturn(\n flag,\n context,\n this.makeResult(flag.defaultValue, 'DEFAULT_VALUE')\n );\n }\n\n /**\n * Evaluate experiment and assign variant.\n */\n private async evaluateExperiment(\n experiment: Experiment,\n context: EvaluationContext\n ): Promise<EvaluationResult | null> {\n const subjectId = getSubjectId(context);\n const subjectType = context.userId\n ? 'user'\n : context.orgId\n ? 'org'\n : 'session';\n\n // Check audience percentage\n const audienceBucket = hashToBucket(\n subjectId,\n `${experiment.key}:audience`\n );\n if (audienceBucket >= experiment.audiencePercentage) {\n return null; // User not in experiment audience\n }\n\n // Check for existing assignment\n let variant = await this.repository.getExperimentAssignment(\n experiment.id,\n subjectType,\n subjectId\n );\n\n if (!variant) {\n // Assign to variant based on consistent hashing\n const variantBucket = hashToBucket(subjectId, experiment.key);\n variant = this.assignVariant(experiment.variants, variantBucket);\n\n // Save assignment\n await this.repository.saveExperimentAssignment(\n experiment.id,\n subjectType,\n subjectId,\n variant,\n variantBucket\n );\n }\n\n // Control variant typically means feature is off\n const enabled = variant !== 'control';\n\n return this.makeResult(\n enabled,\n 'EXPERIMENT_VARIANT',\n variant,\n undefined,\n experiment.id\n );\n }\n\n /**\n * Assign a variant based on bucket and variant percentages.\n */\n private assignVariant(variants: ExperimentVariant[], bucket: number): string {\n let cumulative = 0;\n for (const variant of variants) {\n cumulative += variant.percentage;\n if (bucket < cumulative) {\n return variant.key;\n }\n }\n // Fallback to last variant (shouldn't happen if percentages sum to 100)\n return variants[variants.length - 1]?.key ?? 'control';\n }\n\n /**\n * Create evaluation result.\n */\n private makeResult(\n enabled: boolean,\n reason: EvaluationReason,\n variant?: string,\n ruleId?: string,\n experimentId?: string\n ): EvaluationResult {\n return {\n enabled,\n variant,\n reason,\n ruleId,\n experimentId,\n };\n }\n\n /**\n * Log evaluation and return result.\n */\n private logAndReturn(\n flag: FeatureFlag,\n context: EvaluationContext,\n result: EvaluationResult\n ): EvaluationResult {\n if (this.logEvaluations && this.logger) {\n const subjectId = getSubjectId(context);\n const subjectType = context.userId\n ? 'user'\n : context.orgId\n ? 'org'\n : 'session';\n\n this.logger.log({\n flagId: flag.id,\n flagKey: flag.key,\n subjectType,\n subjectId,\n result: result.enabled,\n variant: result.variant,\n reason: result.reason,\n ruleId: result.ruleId,\n experimentId: result.experimentId,\n context,\n });\n }\n return result;\n }\n}\n\n// ============ In-Memory Repository ============\n\n/**\n * In-memory flag repository for testing and development.\n */\nexport class InMemoryFlagRepository implements FlagRepository {\n private flags = new Map<string, FeatureFlag>();\n private rules = new Map<string, TargetingRule[]>();\n private experiments = new Map<string, Experiment>();\n private assignments = new Map<string, string>();\n\n addFlag(flag: FeatureFlag): void {\n this.flags.set(flag.key, flag);\n }\n\n addRule(flagId: string, rule: TargetingRule): void {\n const existing = this.rules.get(flagId) || [];\n existing.push(rule);\n this.rules.set(flagId, existing);\n }\n\n addExperiment(experiment: Experiment, flagId: string): void {\n this.experiments.set(flagId, experiment);\n }\n\n async getFlag(key: string): Promise<FeatureFlag | null> {\n return this.flags.get(key) || null;\n }\n\n async getRules(flagId: string): Promise<TargetingRule[]> {\n return this.rules.get(flagId) || [];\n }\n\n async getActiveExperiment(flagId: string): Promise<Experiment | null> {\n return this.experiments.get(flagId) || null;\n }\n\n async getExperimentAssignment(\n experimentId: string,\n subjectType: string,\n subjectId: string\n ): Promise<string | null> {\n const key = `${experimentId}:${subjectType}:${subjectId}`;\n return this.assignments.get(key) || null;\n }\n\n async saveExperimentAssignment(\n experimentId: string,\n subjectType: string,\n subjectId: string,\n variant: string\n ): Promise<void> {\n const key = `${experimentId}:${subjectType}:${subjectId}`;\n this.assignments.set(key, variant);\n }\n\n clear(): void {\n this.flags.clear();\n this.rules.clear();\n this.experiments.clear();\n this.assignments.clear();\n }\n}\n"],"mappings":"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"}
package/dist/events.d.ts CHANGED
@@ -621,4 +621,5 @@ declare const FeatureFlagEvents: {
621
621
  }>>;
622
622
  };
623
623
  //#endregion
624
- export { ExperimentCreatedEvent, ExperimentStartedEvent, ExperimentStoppedEvent, FeatureFlagEvents, FlagCreatedEvent, FlagDeletedEvent, FlagEvaluatedEvent, FlagToggledEvent, FlagUpdatedEvent, RuleCreatedEvent, RuleDeletedEvent, VariantAssignedEvent };
624
+ export { ExperimentCreatedEvent, ExperimentStartedEvent, ExperimentStoppedEvent, FeatureFlagEvents, FlagCreatedEvent, FlagDeletedEvent, FlagEvaluatedEvent, FlagToggledEvent, FlagUpdatedEvent, RuleCreatedEvent, RuleDeletedEvent, VariantAssignedEvent };
625
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","names":[],"sources":["../src/events.ts"],"sourcesContent":[],"mappings":";;;;;;;cAsKa,kBAAgB,oBAAA,CAAA,4BAAA;EAAhB,MAAA,EAAA;IAKX,IAAA,EAAA,iBAAA,CAAA,SAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;;qCAL2B,CAAA,MAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAAA;EAAA,CAAA;EAUhB,MAAA,EAAA;IAKX,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;EAL2B,SAAA,EAAA;IAAA,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IAUhB,UAAA,EAAA,IAKX;EAAA,CAAA;;;;;;;;AAKF;AAKE,cAzBW,gBAyBX,EAzB2B,oBAAA,CAAA,SAyB3B,mBAzB2B,WAyB3B,CAAA;;UApBA,iBAAA,CAAA;;;;;gBAe2B,KAAA;EAAA,CAAA;EAAA,OAAA,EAAA;IAUhB,IAAA,6BAKX,CAAA,OAAA,EAAA,OAAA,CAAA;IAAA,UAAA,EAAA,KAAA;;;;;;;qCAL2B,KAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAAA;EAAA,CAAA;AAU7B,CAAA,CAAA,CAAA;;;;cA9Ba,kBAAgB,oBAAA,CAAA,4BAAA;;UAK3B,iBAAA,CAAA,SAyB2B,CAAA,MAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAAA;EAAA,CAAA;EAUhB,GAAA,EAAA;IAKX,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;;qCALiC,KAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAAA;EAAA,CAAA;AAUnC,CAAA,CAAA,CAAA;;;;cAxCa,kBAAgB,oBAAA,CAAA,4BAAA;;UAK3B,iBAAA,CAAA;;;;IAmCiC,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IAAA,UAAA,EAAA,KAAA;EAUtB,CAAA;EAKX,cAAA,EAAA;;;;;;;;EALiC,SAAA,EAAA;IAAA,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IAUtB,UAAA,EAAA,IAAA;EAKX,CAAA;;;;;;;;;cAvDW,gBAkDkB,EAlDF,oBAAA,CAAA,SAkDE,mBAlDF,WAkDE,CAAA;EAAA,MAAA,EAAA;IAAA,IAAA,EA7C7B,iBAAA,CAAA,SA6C6B,CAAA,MAAA,EAAA,MAAA,CAAA;IAUlB,UAAA,EAAA,KAAA;EAKX,CAAA;;;;;;;;;EAL+B,SAAA,EAAA;IAAA,IAAA,6BAAA,CAAA,MAAA,EAAA,MAAA,CAAA;IAUpB,UAAA,EAAA,KAYZ;EAAA,CAAA;;;;;;;;;;;;;cAxEY,kBAAgB,oBAAA,CAAA,4BAAA;;UAK3B,iBAAA,CAAA;;;;;;;;;;;;;;;;;;;cAKW,wBAAsB,oBAAA,CAAA,4BAAA;;UAKjC,iBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAKW,wBAAsB,oBAAA,CAAA,4BAAA;;UAKjC,iBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAKW,wBAAsB,oBAAA,CAAA,4BAAA;;UAKjC,iBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;cAKW,oBAAkB,oBAAA,CAAA,4BAAA;;UAK7B,iBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAKW,sBAAoB,oBAAA,CAAA,4BAAA;;UAK/B,iBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAKW;;;YAYZ,iBAAA,CAAA"}