@breadstone/archipel-mcp 0.0.1
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.
- package/README.md +80 -0
- package/data/packages/index.md +42 -0
- package/data/packages/platform-authentication/api/Class.AnonymousAuthGuard.md +45 -0
- package/data/packages/platform-authentication/api/Class.AuthModule.md +72 -0
- package/data/packages/platform-authentication/api/Class.AuthSubjectPort.md +100 -0
- package/data/packages/platform-authentication/api/Class.AuthTokenService.md +64 -0
- package/data/packages/platform-authentication/api/Class.ChallengeService.md +136 -0
- package/data/packages/platform-authentication/api/Class.GithubAuthGuard.md +45 -0
- package/data/packages/platform-authentication/api/Class.JwtAuthGuard.md +45 -0
- package/data/packages/platform-authentication/api/Class.JwtPayloadBase.md +116 -0
- package/data/packages/platform-authentication/api/Class.LastActiveMiddleware.md +76 -0
- package/data/packages/platform-authentication/api/Class.LocalAuthGuard.md +45 -0
- package/data/packages/platform-authentication/api/Class.MfaService.md +257 -0
- package/data/packages/platform-authentication/api/Class.MfaSubjectPort.md +75 -0
- package/data/packages/platform-authentication/api/Class.RolesGuard.md +65 -0
- package/data/packages/platform-authentication/api/Class.SessionMappingProfile.md +65 -0
- package/data/packages/platform-authentication/api/Class.SessionPersistencePort.md +170 -0
- package/data/packages/platform-authentication/api/Class.SessionResponse.md +157 -0
- package/data/packages/platform-authentication/api/Class.SessionService.md +167 -0
- package/data/packages/platform-authentication/api/Class.SocialAuthGuard.md +66 -0
- package/data/packages/platform-authentication/api/Class.SocialAuthPort.md +53 -0
- package/data/packages/platform-authentication/api/Class.TokenEnricherPort.md +52 -0
- package/data/packages/platform-authentication/api/Class.VerificationService.md +159 -0
- package/data/packages/platform-authentication/api/Class.VerificationSubjectPort.md +121 -0
- package/data/packages/platform-authentication/api/Interface.IAuthModuleOptions.md +89 -0
- package/data/packages/platform-authentication/api/Interface.IAuthSubject.md +112 -0
- package/data/packages/platform-authentication/api/Interface.IMfaChallengePayload.md +87 -0
- package/data/packages/platform-authentication/api/Interface.IMfaChallengeState.md +123 -0
- package/data/packages/platform-authentication/api/Interface.IMfaConfirmation.md +27 -0
- package/data/packages/platform-authentication/api/Interface.IMfaSetup.md +63 -0
- package/data/packages/platform-authentication/api/Interface.IMfaSubject.md +136 -0
- package/data/packages/platform-authentication/api/Interface.IMfaSubjectUpdate.md +96 -0
- package/data/packages/platform-authentication/api/Interface.ISessionRecord.md +165 -0
- package/data/packages/platform-authentication/api/Interface.ISignInResult.md +87 -0
- package/data/packages/platform-authentication/api/Interface.ISocialProfile.md +63 -0
- package/data/packages/platform-authentication/api/Interface.IStoreSessionArgs.md +75 -0
- package/data/packages/platform-authentication/api/Interface.IVerifiableSubject.md +76 -0
- package/data/packages/platform-authentication/api/_media/ENVIRONMENT_VARIABLES.md +151 -0
- package/data/packages/platform-authentication/api/index.md +508 -0
- package/data/packages/platform-authentication/index.md +635 -0
- package/data/packages/platform-blob-storage/api/Class.BlobHealthIndicator.md +84 -0
- package/data/packages/platform-blob-storage/api/Class.BlobModule.md +54 -0
- package/data/packages/platform-blob-storage/api/Class.BlobObjectPersistencePort.md +80 -0
- package/data/packages/platform-blob-storage/api/Class.BlobService.md +253 -0
- package/data/packages/platform-blob-storage/api/Class.BlobVariantPersistencePort.md +56 -0
- package/data/packages/platform-blob-storage/api/Class.VercelBlobProvider.md +202 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobDeleteRequest.md +43 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobDownloadRequest.md +53 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobDownloadResult.md +69 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobModuleOptions.md +53 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobObjectMetadata.md +143 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobProvider.md +119 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobSignedUrlRequest.md +53 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobUploadRequest.md +103 -0
- package/data/packages/platform-blob-storage/api/Interface.IBlobUploadResult.md +33 -0
- package/data/packages/platform-blob-storage/api/Interface.ICustomBlobProviderRegistration.md +33 -0
- package/data/packages/platform-blob-storage/api/Interface.IVercelBlobProviderOptions.md +73 -0
- package/data/packages/platform-blob-storage/api/Interface.IVercelBlobProviderRegistration.md +33 -0
- package/data/packages/platform-blob-storage/api/TypeAlias.BlobDownloadResponseType.md +17 -0
- package/data/packages/platform-blob-storage/api/TypeAlias.BlobUploadBody.md +17 -0
- package/data/packages/platform-blob-storage/api/TypeAlias.IBlobProviderRegistration.md +17 -0
- package/data/packages/platform-blob-storage/api/index.md +111 -0
- package/data/packages/platform-blob-storage/index.md +280 -0
- package/data/packages/platform-core/api/Class.AppHealthIndicator.md +51 -0
- package/data/packages/platform-core/api/Class.BcryptService.md +69 -0
- package/data/packages/platform-core/api/Class.BlobResourceStrategy.md +196 -0
- package/data/packages/platform-core/api/Class.BooleanUtils.md +83 -0
- package/data/packages/platform-core/api/Class.CUIDGenerator.md +121 -0
- package/data/packages/platform-core/api/Class.CasingInterceptor.md +84 -0
- package/data/packages/platform-core/api/Class.CatchUtils.md +94 -0
- package/data/packages/platform-core/api/Class.ConfigModule.md +70 -0
- package/data/packages/platform-core/api/Class.ConfigRegistry.md +116 -0
- package/data/packages/platform-core/api/Class.ConfigService.md +139 -0
- package/data/packages/platform-core/api/Class.ConfigStrategyBase.md +110 -0
- package/data/packages/platform-core/api/Class.ContentTemplateEngine.md +64 -0
- package/data/packages/platform-core/api/Class.CryptoService.md +50 -0
- package/data/packages/platform-core/api/Class.DateTimeUtils.md +102 -0
- package/data/packages/platform-core/api/Class.DeviceParserService.md +53 -0
- package/data/packages/platform-core/api/Class.EmbeddedResourceStrategy.md +216 -0
- package/data/packages/platform-core/api/Class.EnvironmentConfigStrategy.md +144 -0
- package/data/packages/platform-core/api/Class.ErrorTemplateService.md +110 -0
- package/data/packages/platform-core/api/Class.EventHub.md +164 -0
- package/data/packages/platform-core/api/Class.EventModule.md +23 -0
- package/data/packages/platform-core/api/Class.FileConfigStrategy.md +150 -0
- package/data/packages/platform-core/api/Class.FileResourceStrategy.md +193 -0
- package/data/packages/platform-core/api/Class.GUIDGenerator.md +86 -0
- package/data/packages/platform-core/api/Class.GlobalExceptionFilter.md +67 -0
- package/data/packages/platform-core/api/Class.HealthModule.md +43 -0
- package/data/packages/platform-core/api/Class.HealthOrchestrator.md +65 -0
- package/data/packages/platform-core/api/Class.HostModule.md +33 -0
- package/data/packages/platform-core/api/Class.HostService.md +150 -0
- package/data/packages/platform-core/api/Class.HttpLoggerMiddleware.md +60 -0
- package/data/packages/platform-core/api/Class.IdGeneratorBase.md +88 -0
- package/data/packages/platform-core/api/Class.IdentifierModule.md +41 -0
- package/data/packages/platform-core/api/Class.IntelligenceCapabilityRegistrarBase.md +39 -0
- package/data/packages/platform-core/api/Class.IntelligenceCapabilityRegistry.md +103 -0
- package/data/packages/platform-core/api/Class.IntelligenceModule.md +23 -0
- package/data/packages/platform-core/api/Class.IntelligenceTextGenerator.md +82 -0
- package/data/packages/platform-core/api/Class.LimitRequestSizeMiddleware.md +60 -0
- package/data/packages/platform-core/api/Class.LocalizedTextRequest.md +43 -0
- package/data/packages/platform-core/api/Class.LocalizedTextResponse.md +43 -0
- package/data/packages/platform-core/api/Class.MappingBuilder.md +111 -0
- package/data/packages/platform-core/api/Class.MappingModule.md +47 -0
- package/data/packages/platform-core/api/Class.MappingNotRegisteredError.md +57 -0
- package/data/packages/platform-core/api/Class.MappingProfileBase.md +53 -0
- package/data/packages/platform-core/api/Class.MappingService.md +285 -0
- package/data/packages/platform-core/api/Class.MemoryLayeredCache.md +251 -0
- package/data/packages/platform-core/api/Class.NoopCacheMetricsRecorder.md +157 -0
- package/data/packages/platform-core/api/Class.NormalizedUtils.md +149 -0
- package/data/packages/platform-core/api/Class.OtpService.md +106 -0
- package/data/packages/platform-core/api/Class.PageableRequest.md +43 -0
- package/data/packages/platform-core/api/Class.PageableResponse.md +63 -0
- package/data/packages/platform-core/api/Class.ProblemDetailException.md +62 -0
- package/data/packages/platform-core/api/Class.ProblemDetailExceptionFilter.md +85 -0
- package/data/packages/platform-core/api/Class.QuantityResponse.md +43 -0
- package/data/packages/platform-core/api/Class.RedisLayeredCache.md +275 -0
- package/data/packages/platform-core/api/Class.ResourceManager.md +566 -0
- package/data/packages/platform-core/api/Class.ResourceModule.md +47 -0
- package/data/packages/platform-core/api/Class.ResponseReturn.md +504 -0
- package/data/packages/platform-core/api/Class.SseHub.md +184 -0
- package/data/packages/platform-core/api/Class.SseModule.md +43 -0
- package/data/packages/platform-core/api/Class.TimeStampResponse.md +43 -0
- package/data/packages/platform-core/api/Class.TypeMappingNotRegisteredError.md +58 -0
- package/data/packages/platform-core/api/Class.UUIDGenerator.md +86 -0
- package/data/packages/platform-core/api/Class.UserAvatarGeneratorService.md +48 -0
- package/data/packages/platform-core/api/Class.UserNameGeneratorService.md +65 -0
- package/data/packages/platform-core/api/Interface.IBlobResourceStrategyConfig.md +29 -0
- package/data/packages/platform-core/api/Interface.IBlobServiceAdapter.md +41 -0
- package/data/packages/platform-core/api/Interface.ICacheMetricsRecorder.md +121 -0
- package/data/packages/platform-core/api/Interface.ICacheStats.md +71 -0
- package/data/packages/platform-core/api/Interface.IConfigKey.md +64 -0
- package/data/packages/platform-core/api/Interface.IConfigModuleOptions.md +41 -0
- package/data/packages/platform-core/api/Interface.IConfigRegistryEntry.md +80 -0
- package/data/packages/platform-core/api/Interface.IDeviceInfo.md +81 -0
- package/data/packages/platform-core/api/Interface.IErrorPageParams.md +154 -0
- package/data/packages/platform-core/api/Interface.IEventKey.md +58 -0
- package/data/packages/platform-core/api/Interface.IEventMap.md +17 -0
- package/data/packages/platform-core/api/Interface.IFileResourceStrategyConfig.md +73 -0
- package/data/packages/platform-core/api/Interface.IHealthCheckResult.md +47 -0
- package/data/packages/platform-core/api/Interface.IHealthIndicator.md +42 -0
- package/data/packages/platform-core/api/Interface.IHostContentParams.md +233 -0
- package/data/packages/platform-core/api/Interface.IIdGenerator.md +58 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceArtifact.md +31 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceCapability.md +62 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceCapabilityMetadata.md +61 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceCapabilityPayload.md +41 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceCapabilityRegistry.md +69 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceCapabilityResult.md +41 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceCompletionUsage.md +41 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceContext.md +63 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceContextBuilder.md +32 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceConversationMessageSnapshot.md +61 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceConversationSnapshot.md +51 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceFollowUpQuestion.md +41 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceIntent.md +41 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceIntentEntity.md +31 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceMessageModel.md +61 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceMessagePayload.md +31 -0
- package/data/packages/platform-core/api/Interface.IIntelligencePrompt.md +31 -0
- package/data/packages/platform-core/api/Interface.IIntelligencePromptMessage.md +31 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceProviderConfiguration.md +81 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceResponseMessage.md +31 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceTextCompletion.md +53 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceTextGenerationOptions.md +41 -0
- package/data/packages/platform-core/api/Interface.IIntelligenceTextGenerator.md +46 -0
- package/data/packages/platform-core/api/Interface.ILayeredCache.md +194 -0
- package/data/packages/platform-core/api/Interface.ILayeredCacheOptions.md +71 -0
- package/data/packages/platform-core/api/Interface.IMappingBuilder.md +77 -0
- package/data/packages/platform-core/api/Interface.IMappingKey.md +59 -0
- package/data/packages/platform-core/api/Interface.IMappingProfile.md +33 -0
- package/data/packages/platform-core/api/Interface.IOtpService.md +78 -0
- package/data/packages/platform-core/api/Interface.IOtpUriOptions.md +47 -0
- package/data/packages/platform-core/api/Interface.IRedisLayeredCacheOptions.md +108 -0
- package/data/packages/platform-core/api/Interface.IResourceManagerConfig.md +72 -0
- package/data/packages/platform-core/api/Interface.IResourceMetadata.md +95 -0
- package/data/packages/platform-core/api/Interface.IResourceResult.md +35 -0
- package/data/packages/platform-core/api/Interface.IResourceStrategy.md +135 -0
- package/data/packages/platform-core/api/Interface.ISseEventData.md +37 -0
- package/data/packages/platform-core/api/Interface.ISseHub.md +92 -0
- package/data/packages/platform-core/api/Namespace.ISseEventData.md +34 -0
- package/data/packages/platform-core/api/TypeAlias.CamelCase.md +19 -0
- package/data/packages/platform-core/api/TypeAlias.IntelligenceConversationMessageRole.md +16 -0
- package/data/packages/platform-core/api/TypeAlias.IntelligenceProviderName.md +15 -0
- package/data/packages/platform-core/api/TypeAlias.ProblemDetail.md +29 -0
- package/data/packages/platform-core/api/TypeAlias.ProblemDetailTypeUrlResolver.md +26 -0
- package/data/packages/platform-core/api/TypeAlias.SetOptional.md +22 -0
- package/data/packages/platform-core/api/TypeAlias.StringValue.md +13 -0
- package/data/packages/platform-core/api/index.md +645 -0
- package/data/packages/platform-core/index.md +483 -0
- package/data/packages/platform-database/api/Class.DatabaseHealthIndicator.md +80 -0
- package/data/packages/platform-database/api/Class.DatabaseModule.md +75 -0
- package/data/packages/platform-database/api/Class.DatabaseService.md +165 -0
- package/data/packages/platform-database/api/Class.PrismaService.md +116 -0
- package/data/packages/platform-database/api/Class.RepositoryBase.md +526 -0
- package/data/packages/platform-database/api/Class.RepositoryExceptionFilter.md +60 -0
- package/data/packages/platform-database/api/Interface.IDatabaseModuleConfig.md +27 -0
- package/data/packages/platform-database/api/Interface.IPaginateOptions.md +33 -0
- package/data/packages/platform-database/api/Interface.IPaginatedResult.md +82 -0
- package/data/packages/platform-database/api/Interface.IRepositoryQuery.md +56 -0
- package/data/packages/platform-database/api/Interface.ITransactionalRepositoryQuery.md +55 -0
- package/data/packages/platform-database/api/TypeAlias.DelegateArgs.md +23 -0
- package/data/packages/platform-database/api/TypeAlias.DelegateReturnTypes.md +23 -0
- package/data/packages/platform-database/api/TypeAlias.PaginateFunction.md +36 -0
- package/data/packages/platform-database/api/TypeAlias.QueryResultType.md +32 -0
- package/data/packages/platform-database/api/TypeAlias.TransactionalQueryResultType.md +31 -0
- package/data/packages/platform-database/api/index.md +183 -0
- package/data/packages/platform-database/index.md +300 -0
- package/data/packages/platform-documents/api/Class.BaseDocumentRenderer.md +103 -0
- package/data/packages/platform-documents/api/Class.DocumentEngine.md +85 -0
- package/data/packages/platform-documents/api/Class.DocumentModule.md +52 -0
- package/data/packages/platform-documents/api/Class.SharpImageProcessor.md +136 -0
- package/data/packages/platform-documents/api/Interface.IDocumentModuleOptions.md +100 -0
- package/data/packages/platform-documents/api/Interface.IDocumentPlaceholderDetail.md +75 -0
- package/data/packages/platform-documents/api/Interface.IDocumentProbeReport.md +123 -0
- package/data/packages/platform-documents/api/Interface.IDocumentRenderer.md +52 -0
- package/data/packages/platform-documents/api/Interface.IImagePayload.md +63 -0
- package/data/packages/platform-documents/api/Interface.IImageProcessor.md +100 -0
- package/data/packages/platform-documents/api/Interface.IRenderOptions.md +69 -0
- package/data/packages/platform-documents/api/Interface.IRenderResult.md +63 -0
- package/data/packages/platform-documents/api/TypeAlias.DocumentFormat.md +19 -0
- package/data/packages/platform-documents/api/TypeAlias.EngineType.md +19 -0
- package/data/packages/platform-documents/api/TypeAlias.ImageMimeType.md +19 -0
- package/data/packages/platform-documents/api/TypeAlias.TemplateFormat.md +19 -0
- package/data/packages/platform-documents/api/TypeAlias.TemplateType.md +19 -0
- package/data/packages/platform-documents/api/index.md +91 -0
- package/data/packages/platform-documents/index.md +219 -0
- package/data/packages/platform-logging/api/Class.AnalyticsService.md +113 -0
- package/data/packages/platform-logging/api/Class.LoggerModule.md +25 -0
- package/data/packages/platform-logging/api/index.md +42 -0
- package/data/packages/platform-logging/index.md +92 -0
- package/data/packages/platform-mailing/api/Class.BlobTemplateFetchStrategy.md +67 -0
- package/data/packages/platform-mailing/api/Class.DeliveryStrategyBase.md +55 -0
- package/data/packages/platform-mailing/api/Class.FileTemplateFetchStrategy.md +65 -0
- package/data/packages/platform-mailing/api/Class.LogDeliveryStrategy.md +82 -0
- package/data/packages/platform-mailing/api/Class.MailHealthIndicator.md +83 -0
- package/data/packages/platform-mailing/api/Class.MailModule.md +27 -0
- package/data/packages/platform-mailing/api/Class.MailService.md +101 -0
- package/data/packages/platform-mailing/api/Class.MailTemplateEngine.md +98 -0
- package/data/packages/platform-mailing/api/Class.MailVerificationService.md +90 -0
- package/data/packages/platform-mailing/api/Class.MailgunDeliveryStrategy.md +82 -0
- package/data/packages/platform-mailing/api/Class.PostmarkDeliveryStrategy.md +82 -0
- package/data/packages/platform-mailing/api/Class.ResendDeliveryStrategy.md +82 -0
- package/data/packages/platform-mailing/api/Class.SendGridDeliveryStrategy.md +82 -0
- package/data/packages/platform-mailing/api/Class.SmtpDeliveryStrategy.md +82 -0
- package/data/packages/platform-mailing/api/Class.TemplateFetchStrategyBase.md +42 -0
- package/data/packages/platform-mailing/api/Interface.IMailEvents.md +71 -0
- package/data/packages/platform-mailing/api/Interface.IMailTemplateVariants.md +35 -0
- package/data/packages/platform-mailing/api/TypeAlias.MailTemplateFormat.md +19 -0
- package/data/packages/platform-mailing/api/index.md +404 -0
- package/data/packages/platform-mailing/index.md +335 -0
- package/data/packages/platform-mcp/api/Class.McpDiscoveryService.md +65 -0
- package/data/packages/platform-mcp/api/Class.McpModule.md +83 -0
- package/data/packages/platform-mcp/api/Class.McpRegistryService.md +147 -0
- package/data/packages/platform-mcp/api/Class.McpServerService.md +197 -0
- package/data/packages/platform-mcp/api/Interface.IMcpHandlerMetadata.md +47 -0
- package/data/packages/platform-mcp/api/Interface.IMcpModuleAsyncOptions.md +76 -0
- package/data/packages/platform-mcp/api/Interface.IMcpModuleOptions.md +126 -0
- package/data/packages/platform-mcp/api/Interface.IMcpModuleOptionsFactory.md +28 -0
- package/data/packages/platform-mcp/api/Interface.IMcpPromptMetadata.md +59 -0
- package/data/packages/platform-mcp/api/Interface.IMcpResourceMetadata.md +73 -0
- package/data/packages/platform-mcp/api/Interface.IMcpToolMetadata.md +83 -0
- package/data/packages/platform-mcp/api/Interface.IRegisteredPrompt.md +41 -0
- package/data/packages/platform-mcp/api/Interface.IRegisteredResource.md +41 -0
- package/data/packages/platform-mcp/api/Interface.IRegisteredTool.md +41 -0
- package/data/packages/platform-mcp/api/Interface.ISseTransportOptions.md +23 -0
- package/data/packages/platform-mcp/api/Interface.IStreamableHttpTransportOptions.md +39 -0
- package/data/packages/platform-mcp/api/index.md +123 -0
- package/data/packages/platform-mcp/index.md +299 -0
- package/data/packages/platform-openapi/api/Class.SwaggerFeatureDiscovery.md +71 -0
- package/data/packages/platform-openapi/api/Class.SwaggerFeatureRegistry.md +104 -0
- package/data/packages/platform-openapi/api/Class.SwaggerMultiDocumentService.md +82 -0
- package/data/packages/platform-openapi/api/Class.SwaggerTheme.md +51 -0
- package/data/packages/platform-openapi/api/Interface.IFeatureSwaggerConfig.md +73 -0
- package/data/packages/platform-openapi/api/Interface.ISwaggerFeatureMetadata.md +73 -0
- package/data/packages/platform-openapi/api/index.md +209 -0
- package/data/packages/platform-openapi/index.md +170 -0
- package/data/packages/platform-payments/api/Class.FeatureAccessPort.md +79 -0
- package/data/packages/platform-payments/api/Class.FeatureGuard.md +73 -0
- package/data/packages/platform-payments/api/Class.FeatureUsageInterceptor.md +74 -0
- package/data/packages/platform-payments/api/Class.LemonSqueezyClient.md +168 -0
- package/data/packages/platform-payments/api/Class.MollieClient.md +168 -0
- package/data/packages/platform-payments/api/Class.PaddleClient.md +168 -0
- package/data/packages/platform-payments/api/Class.PaymentClientPort.md +147 -0
- package/data/packages/platform-payments/api/Class.PaymentModule.md +53 -0
- package/data/packages/platform-payments/api/Class.StripeClient.md +168 -0
- package/data/packages/platform-payments/api/Interface.IFeatureAccessResult.md +75 -0
- package/data/packages/platform-payments/api/Interface.INormalizedCheckoutSession.md +75 -0
- package/data/packages/platform-payments/api/Interface.INormalizedPrice.md +85 -0
- package/data/packages/platform-payments/api/Interface.INormalizedSubscription.md +105 -0
- package/data/packages/platform-payments/api/Interface.INormalizedWebhookEvent.md +89 -0
- package/data/packages/platform-payments/api/Interface.IPaymentModuleOptions.md +65 -0
- package/data/packages/platform-payments/api/TypeAlias.SubscriptionStatus.md +27 -0
- package/data/packages/platform-payments/api/index.md +243 -0
- package/data/packages/platform-payments/index.md +532 -0
- package/data/packages/platform-reporting/api/Class.ReportingContributorRegistry.md +57 -0
- package/data/packages/platform-reporting/api/Class.ReportingDatasetNotFoundError.md +41 -0
- package/data/packages/platform-reporting/api/Class.ReportingFacade.md +85 -0
- package/data/packages/platform-reporting/api/Class.ReportingModule.md +23 -0
- package/data/packages/platform-reporting/api/Interface.IReportingContributor.md +62 -0
- package/data/packages/platform-reporting/api/Interface.IReportingDataset.md +83 -0
- package/data/packages/platform-reporting/api/Interface.IReportingDatasetField.md +71 -0
- package/data/packages/platform-reporting/api/Interface.IReportingQuery.md +61 -0
- package/data/packages/platform-reporting/api/Interface.IReportingQueryFilter.md +41 -0
- package/data/packages/platform-reporting/api/Interface.IReportingQueryResult.md +61 -0
- package/data/packages/platform-reporting/api/Interface.IReportingQuerySort.md +31 -0
- package/data/packages/platform-reporting/api/TypeAlias.ReportingFieldType.md +13 -0
- package/data/packages/platform-reporting/api/TypeAlias.ReportingFilterOperator.md +13 -0
- package/data/packages/platform-reporting/api/TypeAlias.ReportingQueryResultRow.md +15 -0
- package/data/packages/platform-reporting/api/index.md +90 -0
- package/data/packages/platform-reporting/index.md +229 -0
- package/data/packages/platform-telemetry/api/Class.NoopTelemetryFacade.md +118 -0
- package/data/packages/platform-telemetry/api/Class.TelemetryCacheMetricsRecorder.md +180 -0
- package/data/packages/platform-telemetry/api/Class.TelemetryFacade.md +132 -0
- package/data/packages/platform-telemetry/api/Class.TelemetryLoggerService.md +231 -0
- package/data/packages/platform-telemetry/api/Class.TelemetryModule.md +45 -0
- package/data/packages/platform-telemetry/api/Class.TelemetryRuleEngine.md +53 -0
- package/data/packages/platform-telemetry/api/Interface.ITelemetryFacade.md +90 -0
- package/data/packages/platform-telemetry/api/Interface.ITelemetryMetricsOptions.md +43 -0
- package/data/packages/platform-telemetry/api/Interface.ITelemetryOptions.md +141 -0
- package/data/packages/platform-telemetry/api/Interface.ITelemetryTracesOptions.md +43 -0
- package/data/packages/platform-telemetry/api/index.md +81 -0
- package/data/packages/platform-telemetry/index.md +234 -0
- package/package.json +39 -0
- package/src/DocsLoader.d.ts +14 -0
- package/src/DocsLoader.js +103 -0
- package/src/knowledge/configPattern.d.ts +5 -0
- package/src/knowledge/configPattern.js +211 -0
- package/src/knowledge/dtoPattern.d.ts +5 -0
- package/src/knowledge/dtoPattern.js +286 -0
- package/src/knowledge/errorHandlingPattern.d.ts +5 -0
- package/src/knowledge/errorHandlingPattern.js +219 -0
- package/src/knowledge/guardPattern.d.ts +5 -0
- package/src/knowledge/guardPattern.js +256 -0
- package/src/knowledge/mappingPattern.d.ts +6 -0
- package/src/knowledge/mappingPattern.js +322 -0
- package/src/knowledge/modulePattern.d.ts +6 -0
- package/src/knowledge/modulePattern.js +283 -0
- package/src/knowledge/queryPattern.d.ts +6 -0
- package/src/knowledge/queryPattern.js +215 -0
- package/src/knowledge/repositoryPattern.d.ts +6 -0
- package/src/knowledge/repositoryPattern.js +367 -0
- package/src/knowledge/testingPattern.d.ts +5 -0
- package/src/knowledge/testingPattern.js +356 -0
- package/src/main.d.ts +2 -0
- package/src/main.js +226 -0
- package/src/models/IPackageDoc.d.ts +19 -0
- package/src/models/IPackageDoc.js +3 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Static knowledge content for the Archipel error handling pattern.
|
|
4
|
+
* Returned by the get-error-handling-pattern tool.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ERROR_HANDLING_PATTERN_KNOWLEDGE = void 0;
|
|
8
|
+
exports.ERROR_HANDLING_PATTERN_KNOWLEDGE = `# Archipel Error Handling Pattern
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Archipel uses **domain-specific error classes** that are caught by **global exception filters**
|
|
13
|
+
and mapped to structured HTTP responses. Services throw domain errors; the framework handles
|
|
14
|
+
the HTTP translation. This keeps business logic clean and error responses consistent.
|
|
15
|
+
|
|
16
|
+
## Layer Architecture
|
|
17
|
+
|
|
18
|
+
\`\`\`
|
|
19
|
+
Service → throws DomainError → ExceptionFilter → HTTP Response Envelope
|
|
20
|
+
\`\`\`
|
|
21
|
+
|
|
22
|
+
## Base Error Classes
|
|
23
|
+
|
|
24
|
+
### RepositoryError
|
|
25
|
+
|
|
26
|
+
Thrown when any Prisma operation fails. Automatically wrapped by \`RepositoryBase.tryCatch()\`.
|
|
27
|
+
|
|
28
|
+
\`\`\`typescript
|
|
29
|
+
// models/errors/RepositoryError.ts
|
|
30
|
+
export class RepositoryError extends Error {
|
|
31
|
+
|
|
32
|
+
public readonly code = 'REPOSITORY_ERROR';
|
|
33
|
+
public readonly originalCode?: string;
|
|
34
|
+
public readonly meta?: Record<string, unknown>;
|
|
35
|
+
|
|
36
|
+
public constructor(message: string, originalCode?: string, meta?: Record<string, unknown>) {
|
|
37
|
+
super(message);
|
|
38
|
+
Object.setPrototypeOf(this, RepositoryError.prototype);
|
|
39
|
+
this.name = 'RepositoryError';
|
|
40
|
+
this.originalCode = originalCode;
|
|
41
|
+
this.meta = meta;
|
|
42
|
+
|
|
43
|
+
if (Error.captureStackTrace) {
|
|
44
|
+
Error.captureStackTrace(this, RepositoryError);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
### MappingError (abstract)
|
|
52
|
+
|
|
53
|
+
Base for mapping-related errors.
|
|
54
|
+
|
|
55
|
+
\`\`\`typescript
|
|
56
|
+
export abstract class MappingError extends Error {
|
|
57
|
+
public readonly code: string;
|
|
58
|
+
|
|
59
|
+
protected constructor(message: string, code: string) {
|
|
60
|
+
super(message);
|
|
61
|
+
this.code = code;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
Concrete variants:
|
|
67
|
+
- \`MappingNotRegisteredError\` — code: \`'MAPPING_NOT_REGISTERED'\`
|
|
68
|
+
- \`TypeMappingNotRegisteredError\` — code: \`'TYPE_MAPPING_NOT_REGISTERED'\`
|
|
69
|
+
|
|
70
|
+
## Exception Filters
|
|
71
|
+
|
|
72
|
+
### RepositoryExceptionFilter
|
|
73
|
+
|
|
74
|
+
\`\`\`typescript
|
|
75
|
+
import { ArgumentsHost, Catch, ExceptionFilter, HttpStatus } from '@nestjs/common';
|
|
76
|
+
import { Request, Response } from 'express';
|
|
77
|
+
import { RepositoryError } from '../models/errors/RepositoryError';
|
|
78
|
+
|
|
79
|
+
@Catch(RepositoryError)
|
|
80
|
+
export class RepositoryExceptionFilter implements ExceptionFilter<RepositoryError> {
|
|
81
|
+
|
|
82
|
+
public catch(_exception: RepositoryError, host: ArgumentsHost): void {
|
|
83
|
+
const ctx = host.switchToHttp();
|
|
84
|
+
const response = ctx.getResponse<Response>();
|
|
85
|
+
const request = ctx.getRequest<Request>();
|
|
86
|
+
|
|
87
|
+
response.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
|
|
88
|
+
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
89
|
+
timestamp: new Date().toISOString(),
|
|
90
|
+
error: 'Repository Error',
|
|
91
|
+
path: request.url,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
\`\`\`
|
|
97
|
+
|
|
98
|
+
### Registration (in main.ts or AppModule)
|
|
99
|
+
|
|
100
|
+
\`\`\`typescript
|
|
101
|
+
app.useGlobalFilters(new RepositoryExceptionFilter());
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
## How to Create a Domain Error
|
|
105
|
+
|
|
106
|
+
### Step 1: Define the error class
|
|
107
|
+
|
|
108
|
+
\`\`\`typescript
|
|
109
|
+
// models/errors/UserNotFoundError.ts
|
|
110
|
+
export class UserNotFoundError extends Error {
|
|
111
|
+
|
|
112
|
+
public readonly code = 'USER_NOT_FOUND';
|
|
113
|
+
public readonly userId: string;
|
|
114
|
+
|
|
115
|
+
public constructor(userId: string) {
|
|
116
|
+
super(\\\`User not found: \\\${userId}\\\`);
|
|
117
|
+
Object.setPrototypeOf(this, UserNotFoundError.prototype);
|
|
118
|
+
this.name = 'UserNotFoundError';
|
|
119
|
+
this.userId = userId;
|
|
120
|
+
|
|
121
|
+
if (Error.captureStackTrace) {
|
|
122
|
+
Error.captureStackTrace(this, UserNotFoundError);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
\`\`\`
|
|
128
|
+
|
|
129
|
+
### Step 2: Create an exception filter
|
|
130
|
+
|
|
131
|
+
\`\`\`typescript
|
|
132
|
+
// filters/UserNotFoundExceptionFilter.ts
|
|
133
|
+
import { ArgumentsHost, Catch, ExceptionFilter, HttpStatus } from '@nestjs/common';
|
|
134
|
+
import { Request, Response } from 'express';
|
|
135
|
+
import { UserNotFoundError } from '../models/errors/UserNotFoundError';
|
|
136
|
+
|
|
137
|
+
@Catch(UserNotFoundError)
|
|
138
|
+
export class UserNotFoundExceptionFilter implements ExceptionFilter<UserNotFoundError> {
|
|
139
|
+
|
|
140
|
+
public catch(exception: UserNotFoundError, host: ArgumentsHost): void {
|
|
141
|
+
const ctx = host.switchToHttp();
|
|
142
|
+
const response = ctx.getResponse<Response>();
|
|
143
|
+
const request = ctx.getRequest<Request>();
|
|
144
|
+
|
|
145
|
+
response.status(HttpStatus.NOT_FOUND).json({
|
|
146
|
+
statusCode: HttpStatus.NOT_FOUND,
|
|
147
|
+
timestamp: new Date().toISOString(),
|
|
148
|
+
error: exception.code,
|
|
149
|
+
message: exception.message,
|
|
150
|
+
path: request.url,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
\`\`\`
|
|
156
|
+
|
|
157
|
+
### Step 3: Register the filter globally
|
|
158
|
+
|
|
159
|
+
\`\`\`typescript
|
|
160
|
+
app.useGlobalFilters(
|
|
161
|
+
new RepositoryExceptionFilter(),
|
|
162
|
+
new UserNotFoundExceptionFilter(),
|
|
163
|
+
);
|
|
164
|
+
\`\`\`
|
|
165
|
+
|
|
166
|
+
### Step 4: Throw from a service
|
|
167
|
+
|
|
168
|
+
\`\`\`typescript
|
|
169
|
+
@Injectable()
|
|
170
|
+
export class UserService {
|
|
171
|
+
|
|
172
|
+
public async findById(id: string): Promise<IUserEntity> {
|
|
173
|
+
const user = await this._userRepository.execute(findUserByIdQuery(id));
|
|
174
|
+
|
|
175
|
+
if (!user) {
|
|
176
|
+
throw new UserNotFoundError(id);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return user;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
}
|
|
183
|
+
\`\`\`
|
|
184
|
+
|
|
185
|
+
## Response Envelope Convention
|
|
186
|
+
|
|
187
|
+
All error responses follow the same shape:
|
|
188
|
+
|
|
189
|
+
\`\`\`json
|
|
190
|
+
{
|
|
191
|
+
"statusCode": 404,
|
|
192
|
+
"timestamp": "2026-04-05T12:00:00.000Z",
|
|
193
|
+
"error": "USER_NOT_FOUND",
|
|
194
|
+
"message": "User not found: abc-123",
|
|
195
|
+
"path": "/api/v1/users/abc-123"
|
|
196
|
+
}
|
|
197
|
+
\`\`\`
|
|
198
|
+
|
|
199
|
+
## Prisma Error Code Reference
|
|
200
|
+
|
|
201
|
+
Common Prisma error codes wrapped by \`RepositoryError\`:
|
|
202
|
+
|
|
203
|
+
| Code | Meaning |
|
|
204
|
+
|------|---------|
|
|
205
|
+
| P2000 | Value too long |
|
|
206
|
+
| P2002 | Unique constraint violation |
|
|
207
|
+
| P2003 | Foreign key constraint violation |
|
|
208
|
+
| P2025 | Record not found |
|
|
209
|
+
|
|
210
|
+
## Rules
|
|
211
|
+
|
|
212
|
+
1. **Services throw domain errors** — never raw NestJS HttpException in service layer.
|
|
213
|
+
2. **Exception filters map to HTTP** — one filter per domain error type.
|
|
214
|
+
3. **Error classes include a machine-readable \`code\`** — used for client-side error handling.
|
|
215
|
+
4. **Use \`Object.setPrototypeOf\`** and \`Error.captureStackTrace\` in custom Error subclasses.
|
|
216
|
+
5. **Don't leak internal details** — the filter should not expose Prisma error codes or stack traces.
|
|
217
|
+
6. **Register filters globally** in the bootstrap function or via \`APP_FILTER\` provider.
|
|
218
|
+
`;
|
|
219
|
+
//# sourceMappingURL=errorHandlingPattern.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static knowledge content for the Archipel guard & interceptor pattern.
|
|
3
|
+
* Returned by the get-guard-pattern tool.
|
|
4
|
+
*/
|
|
5
|
+
export declare const GUARD_PATTERN_KNOWLEDGE = "# Archipel Guard & Interceptor Pattern\n\n## Overview\n\nArchipel uses a **metadata-driven** guard and interceptor pattern. A custom decorator\nattaches metadata (e.g., a feature key or role) to the handler. The guard reads this\nmetadata to decide access. An optional interceptor runs after the handler to record\nusage or perform side effects.\n\nThis creates a reusable trio: **Decorator \u2192 Guard \u2192 Interceptor**.\n\n## Guard Architecture\n\n```\n@RequiresFeature('create-posts') \u2190 Decorator sets metadata\n@UseGuards(JwtAuthGuard, FeatureGuard) \u2190 Guard reads metadata, checks access\n@UseInterceptors(FeatureUsageInterceptor) \u2190 Interceptor records usage after success\n```\n\n## Available Guards\n\n| Guard | Strategy | Purpose |\n|-------|----------|---------|\n| `JwtAuthGuard` | jwt | Validates JWT bearer token |\n| `LocalAuthGuard` | local | Validates username + password |\n| `AnonymousAuthGuard` | anonymous | Allows unauthenticated access with a seed user |\n| `GithubAuthGuard` | github | OAuth via GitHub |\n| `RolesGuard` | metadata | Checks user roles against required roles |\n| `FeatureGuard` | metadata + port | Checks feature access via FeatureAccessPort |\n\n## The Feature Guard Pattern (Full Example)\n\n### Step 1: Metadata Decorator\n\n```typescript\nimport { SetMetadata } from '@nestjs/common';\n\nexport const FEATURE_KEY_METADATA = 'feature_key';\n\nexport const RequiresFeature = (featureKey: string) =>\n SetMetadata(FEATURE_KEY_METADATA, featureKey);\n```\n\n### Step 2: Guard\n\n```typescript\nimport { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { FeatureAccessPort } from '../contracts/FeatureAccessPort';\n\n@Injectable()\nexport class FeatureGuard implements CanActivate {\n\n // #region Fields\n\n private readonly _featureAccessPort: FeatureAccessPort;\n private readonly _reflector: Reflector;\n\n // #endregion\n\n // #region Ctor\n\n public constructor(featureAccessPort: FeatureAccessPort, reflector: Reflector) {\n this._featureAccessPort = featureAccessPort;\n this._reflector = reflector;\n }\n\n // #endregion\n\n // #region Methods\n\n public async canActivate(context: ExecutionContext): Promise<boolean> {\n const featureKey = this._reflector.get<string>(FEATURE_KEY_METADATA, context.getHandler());\n\n if (!featureKey) {\n return true; // No feature requirement on this endpoint\n }\n\n const request = context.switchToHttp().getRequest();\n const user = request.user;\n\n if (!user || !user.id) {\n return false;\n }\n\n const access = await this._featureAccessPort.checkAccess(user.id, featureKey);\n request.featureAccess = access; // Attach for downstream use\n\n return access.allowed;\n }\n\n // #endregion\n\n}\n```\n\n### Step 3: Interceptor (records usage after success)\n\n```typescript\nimport { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { Observable } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n@Injectable()\nexport class FeatureUsageInterceptor implements NestInterceptor {\n\n // #region Fields\n\n private readonly _featureAccessPort: FeatureAccessPort;\n private readonly _reflector: Reflector;\n\n // #endregion\n\n // #region Ctor\n\n public constructor(featureAccessPort: FeatureAccessPort, reflector: Reflector) {\n this._featureAccessPort = featureAccessPort;\n this._reflector = reflector;\n }\n\n // #endregion\n\n // #region Methods\n\n public intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const featureKey = this._reflector.get<string>(FEATURE_KEY_METADATA, context.getHandler());\n\n if (!featureKey) {\n return next.handle();\n }\n\n const request = context.switchToHttp().getRequest();\n const user = request.user;\n\n return next.handle().pipe(\n tap(async () => {\n if (user && user.id) {\n await this._featureAccessPort.recordUsage(user.id, featureKey);\n }\n }),\n );\n }\n\n // #endregion\n\n}\n```\n\n### Step 4: Controller Usage\n\n```typescript\n@Controller('/posts')\nexport class PostsController {\n\n @Post()\n @RequiresFeature('create-posts')\n @UseGuards(JwtAuthGuard, FeatureGuard)\n @UseInterceptors(FeatureUsageInterceptor)\n public async createPost(@Body() body: CreatePostRequest): Promise<PostResponse> {\n const entity = await this._postService.create(body);\n\n return this._mappingService.map(POST_MAPPING_KEY, entity);\n }\n\n}\n```\n\n## Roles Guard Pattern\n\n```typescript\n// Decorator\nexport const Roles = (...roles: string[]) => SetMetadata('roles', roles);\n\n// Guard\n@Injectable()\nexport class RolesGuard implements CanActivate {\n\n public constructor(private readonly _reflector: Reflector) {}\n\n public canActivate(context: ExecutionContext): boolean {\n const requiredRoles = this._reflector.get<string[]>('roles', context.getHandler());\n if (!requiredRoles) return true;\n\n const request = context.switchToHttp().getRequest();\n const user = request.user;\n\n return requiredRoles.some((role) => user.roles?.includes(role));\n }\n\n}\n\n// Usage\n@Get('/admin')\n@Roles('admin', 'superadmin')\n@UseGuards(JwtAuthGuard, RolesGuard)\npublic async getAdminPanel(): Promise<AdminResponse> { ... }\n```\n\n## Telemetry Interceptor\n\n```typescript\n@Injectable()\nexport class OperationTelemetryInterceptor implements NestInterceptor {\n\n private readonly _facade: ITelemetryFacade;\n\n public intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const handler = context.getHandler().name;\n const cls = context.getClass().name;\n // ... start span, capture duration, record outcome\n return next.handle();\n }\n\n}\n```\n\n## How to Create a Custom Guard + Interceptor Pair\n\n### Step 1: Define the metadata key and decorator\n\n```typescript\nexport const RATE_LIMIT_METADATA = 'rate_limit';\nexport const RateLimit = (maxRequests: number) => SetMetadata(RATE_LIMIT_METADATA, maxRequests);\n```\n\n### Step 2: Create the guard\n\nRead metadata via `Reflector`, check the condition, return boolean.\n\n### Step 3: Create the interceptor (optional)\n\nUse `tap()` in the RxJS pipeline to perform post-handler side effects.\n\n### Step 4: Register in the module\n\nExport guard and interceptor from the library module so consumers can apply them.\n\n## Rules\n\n1. **Guards decide access** \u2014 return `true` or `false`, never throw directly.\n2. **Interceptors handle side effects** \u2014 recording, logging, transforming responses.\n3. **Metadata decorators are the glue** \u2014 they attach config to handlers, read by guards/interceptors.\n4. **Auth guards extend Passport's AuthGuard** \u2014 e.g. `AuthGuard('jwt')`.\n5. **Feature guards delegate to ports** \u2014 the guard itself holds no business logic.\n6. **Guard order matters** \u2014 `@UseGuards(AuthGuard, FeatureGuard)`: auth runs first.\n7. **Interceptors use `tap()`** for post-handler logic, `map()` for response transformation.\n";
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Static knowledge content for the Archipel guard & interceptor pattern.
|
|
4
|
+
* Returned by the get-guard-pattern tool.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.GUARD_PATTERN_KNOWLEDGE = void 0;
|
|
8
|
+
exports.GUARD_PATTERN_KNOWLEDGE = `# Archipel Guard & Interceptor Pattern
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Archipel uses a **metadata-driven** guard and interceptor pattern. A custom decorator
|
|
13
|
+
attaches metadata (e.g., a feature key or role) to the handler. The guard reads this
|
|
14
|
+
metadata to decide access. An optional interceptor runs after the handler to record
|
|
15
|
+
usage or perform side effects.
|
|
16
|
+
|
|
17
|
+
This creates a reusable trio: **Decorator → Guard → Interceptor**.
|
|
18
|
+
|
|
19
|
+
## Guard Architecture
|
|
20
|
+
|
|
21
|
+
\`\`\`
|
|
22
|
+
@RequiresFeature('create-posts') ← Decorator sets metadata
|
|
23
|
+
@UseGuards(JwtAuthGuard, FeatureGuard) ← Guard reads metadata, checks access
|
|
24
|
+
@UseInterceptors(FeatureUsageInterceptor) ← Interceptor records usage after success
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
## Available Guards
|
|
28
|
+
|
|
29
|
+
| Guard | Strategy | Purpose |
|
|
30
|
+
|-------|----------|---------|
|
|
31
|
+
| \`JwtAuthGuard\` | jwt | Validates JWT bearer token |
|
|
32
|
+
| \`LocalAuthGuard\` | local | Validates username + password |
|
|
33
|
+
| \`AnonymousAuthGuard\` | anonymous | Allows unauthenticated access with a seed user |
|
|
34
|
+
| \`GithubAuthGuard\` | github | OAuth via GitHub |
|
|
35
|
+
| \`RolesGuard\` | metadata | Checks user roles against required roles |
|
|
36
|
+
| \`FeatureGuard\` | metadata + port | Checks feature access via FeatureAccessPort |
|
|
37
|
+
|
|
38
|
+
## The Feature Guard Pattern (Full Example)
|
|
39
|
+
|
|
40
|
+
### Step 1: Metadata Decorator
|
|
41
|
+
|
|
42
|
+
\`\`\`typescript
|
|
43
|
+
import { SetMetadata } from '@nestjs/common';
|
|
44
|
+
|
|
45
|
+
export const FEATURE_KEY_METADATA = 'feature_key';
|
|
46
|
+
|
|
47
|
+
export const RequiresFeature = (featureKey: string) =>
|
|
48
|
+
SetMetadata(FEATURE_KEY_METADATA, featureKey);
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
### Step 2: Guard
|
|
52
|
+
|
|
53
|
+
\`\`\`typescript
|
|
54
|
+
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
|
55
|
+
import { Reflector } from '@nestjs/core';
|
|
56
|
+
import { FeatureAccessPort } from '../contracts/FeatureAccessPort';
|
|
57
|
+
|
|
58
|
+
@Injectable()
|
|
59
|
+
export class FeatureGuard implements CanActivate {
|
|
60
|
+
|
|
61
|
+
// #region Fields
|
|
62
|
+
|
|
63
|
+
private readonly _featureAccessPort: FeatureAccessPort;
|
|
64
|
+
private readonly _reflector: Reflector;
|
|
65
|
+
|
|
66
|
+
// #endregion
|
|
67
|
+
|
|
68
|
+
// #region Ctor
|
|
69
|
+
|
|
70
|
+
public constructor(featureAccessPort: FeatureAccessPort, reflector: Reflector) {
|
|
71
|
+
this._featureAccessPort = featureAccessPort;
|
|
72
|
+
this._reflector = reflector;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// #endregion
|
|
76
|
+
|
|
77
|
+
// #region Methods
|
|
78
|
+
|
|
79
|
+
public async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
80
|
+
const featureKey = this._reflector.get<string>(FEATURE_KEY_METADATA, context.getHandler());
|
|
81
|
+
|
|
82
|
+
if (!featureKey) {
|
|
83
|
+
return true; // No feature requirement on this endpoint
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const request = context.switchToHttp().getRequest();
|
|
87
|
+
const user = request.user;
|
|
88
|
+
|
|
89
|
+
if (!user || !user.id) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const access = await this._featureAccessPort.checkAccess(user.id, featureKey);
|
|
94
|
+
request.featureAccess = access; // Attach for downstream use
|
|
95
|
+
|
|
96
|
+
return access.allowed;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// #endregion
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
### Step 3: Interceptor (records usage after success)
|
|
105
|
+
|
|
106
|
+
\`\`\`typescript
|
|
107
|
+
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
|
|
108
|
+
import { Reflector } from '@nestjs/core';
|
|
109
|
+
import { Observable } from 'rxjs';
|
|
110
|
+
import { tap } from 'rxjs/operators';
|
|
111
|
+
|
|
112
|
+
@Injectable()
|
|
113
|
+
export class FeatureUsageInterceptor implements NestInterceptor {
|
|
114
|
+
|
|
115
|
+
// #region Fields
|
|
116
|
+
|
|
117
|
+
private readonly _featureAccessPort: FeatureAccessPort;
|
|
118
|
+
private readonly _reflector: Reflector;
|
|
119
|
+
|
|
120
|
+
// #endregion
|
|
121
|
+
|
|
122
|
+
// #region Ctor
|
|
123
|
+
|
|
124
|
+
public constructor(featureAccessPort: FeatureAccessPort, reflector: Reflector) {
|
|
125
|
+
this._featureAccessPort = featureAccessPort;
|
|
126
|
+
this._reflector = reflector;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// #endregion
|
|
130
|
+
|
|
131
|
+
// #region Methods
|
|
132
|
+
|
|
133
|
+
public intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
|
|
134
|
+
const featureKey = this._reflector.get<string>(FEATURE_KEY_METADATA, context.getHandler());
|
|
135
|
+
|
|
136
|
+
if (!featureKey) {
|
|
137
|
+
return next.handle();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const request = context.switchToHttp().getRequest();
|
|
141
|
+
const user = request.user;
|
|
142
|
+
|
|
143
|
+
return next.handle().pipe(
|
|
144
|
+
tap(async () => {
|
|
145
|
+
if (user && user.id) {
|
|
146
|
+
await this._featureAccessPort.recordUsage(user.id, featureKey);
|
|
147
|
+
}
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// #endregion
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
\`\`\`
|
|
156
|
+
|
|
157
|
+
### Step 4: Controller Usage
|
|
158
|
+
|
|
159
|
+
\`\`\`typescript
|
|
160
|
+
@Controller('/posts')
|
|
161
|
+
export class PostsController {
|
|
162
|
+
|
|
163
|
+
@Post()
|
|
164
|
+
@RequiresFeature('create-posts')
|
|
165
|
+
@UseGuards(JwtAuthGuard, FeatureGuard)
|
|
166
|
+
@UseInterceptors(FeatureUsageInterceptor)
|
|
167
|
+
public async createPost(@Body() body: CreatePostRequest): Promise<PostResponse> {
|
|
168
|
+
const entity = await this._postService.create(body);
|
|
169
|
+
|
|
170
|
+
return this._mappingService.map(POST_MAPPING_KEY, entity);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
\`\`\`
|
|
175
|
+
|
|
176
|
+
## Roles Guard Pattern
|
|
177
|
+
|
|
178
|
+
\`\`\`typescript
|
|
179
|
+
// Decorator
|
|
180
|
+
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
|
|
181
|
+
|
|
182
|
+
// Guard
|
|
183
|
+
@Injectable()
|
|
184
|
+
export class RolesGuard implements CanActivate {
|
|
185
|
+
|
|
186
|
+
public constructor(private readonly _reflector: Reflector) {}
|
|
187
|
+
|
|
188
|
+
public canActivate(context: ExecutionContext): boolean {
|
|
189
|
+
const requiredRoles = this._reflector.get<string[]>('roles', context.getHandler());
|
|
190
|
+
if (!requiredRoles) return true;
|
|
191
|
+
|
|
192
|
+
const request = context.switchToHttp().getRequest();
|
|
193
|
+
const user = request.user;
|
|
194
|
+
|
|
195
|
+
return requiredRoles.some((role) => user.roles?.includes(role));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Usage
|
|
201
|
+
@Get('/admin')
|
|
202
|
+
@Roles('admin', 'superadmin')
|
|
203
|
+
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
204
|
+
public async getAdminPanel(): Promise<AdminResponse> { ... }
|
|
205
|
+
\`\`\`
|
|
206
|
+
|
|
207
|
+
## Telemetry Interceptor
|
|
208
|
+
|
|
209
|
+
\`\`\`typescript
|
|
210
|
+
@Injectable()
|
|
211
|
+
export class OperationTelemetryInterceptor implements NestInterceptor {
|
|
212
|
+
|
|
213
|
+
private readonly _facade: ITelemetryFacade;
|
|
214
|
+
|
|
215
|
+
public intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
|
|
216
|
+
const handler = context.getHandler().name;
|
|
217
|
+
const cls = context.getClass().name;
|
|
218
|
+
// ... start span, capture duration, record outcome
|
|
219
|
+
return next.handle();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
}
|
|
223
|
+
\`\`\`
|
|
224
|
+
|
|
225
|
+
## How to Create a Custom Guard + Interceptor Pair
|
|
226
|
+
|
|
227
|
+
### Step 1: Define the metadata key and decorator
|
|
228
|
+
|
|
229
|
+
\`\`\`typescript
|
|
230
|
+
export const RATE_LIMIT_METADATA = 'rate_limit';
|
|
231
|
+
export const RateLimit = (maxRequests: number) => SetMetadata(RATE_LIMIT_METADATA, maxRequests);
|
|
232
|
+
\`\`\`
|
|
233
|
+
|
|
234
|
+
### Step 2: Create the guard
|
|
235
|
+
|
|
236
|
+
Read metadata via \`Reflector\`, check the condition, return boolean.
|
|
237
|
+
|
|
238
|
+
### Step 3: Create the interceptor (optional)
|
|
239
|
+
|
|
240
|
+
Use \`tap()\` in the RxJS pipeline to perform post-handler side effects.
|
|
241
|
+
|
|
242
|
+
### Step 4: Register in the module
|
|
243
|
+
|
|
244
|
+
Export guard and interceptor from the library module so consumers can apply them.
|
|
245
|
+
|
|
246
|
+
## Rules
|
|
247
|
+
|
|
248
|
+
1. **Guards decide access** — return \`true\` or \`false\`, never throw directly.
|
|
249
|
+
2. **Interceptors handle side effects** — recording, logging, transforming responses.
|
|
250
|
+
3. **Metadata decorators are the glue** — they attach config to handlers, read by guards/interceptors.
|
|
251
|
+
4. **Auth guards extend Passport's AuthGuard** — e.g. \`AuthGuard('jwt')\`.
|
|
252
|
+
5. **Feature guards delegate to ports** — the guard itself holds no business logic.
|
|
253
|
+
6. **Guard order matters** — \`@UseGuards(AuthGuard, FeatureGuard)\`: auth runs first.
|
|
254
|
+
7. **Interceptors use \`tap()\`** for post-handler logic, \`map()\` for response transformation.
|
|
255
|
+
`;
|
|
256
|
+
//# sourceMappingURL=guardPattern.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static knowledge content for the Archipel mapping pattern.
|
|
3
|
+
* Returned by the get-mapping-pattern tool.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MAPPING_PATTERN_KNOWLEDGE = "# Archipel Mapping Pattern\n\n## Overview\n\nIn Archipel, all object-to-object mapping goes through a central **MappingService** with\n**branded, type-safe mapping keys**. This guarantees compile-time type safety: the key\nencodes both the input and output type, so calling `mappingService.map(KEY, input)` is\nstatically checked \u2014 the compiler verifies that `input` matches the key's input type and\ninfers the return type automatically.\n\n**Rule:** Services MUST NOT inline-create response objects. They return entities.\nControllers use the MappingService to convert entities to response DTOs.\n\n## Core Types\n\n### IMappingKey<TInput, TOutput>\n\n```typescript\nexport interface IMappingKey<TInput, TOutput> {\n readonly _brand: 'MappingKey';\n readonly _input: TInput;\n readonly _output: TOutput;\n readonly key: string;\n}\n```\n\nThe `_input` and `_output` fields are phantom types \u2014 they exist only for compile-time\ntype encoding and are never accessed at runtime.\n\n### createMappingKey<TInput, TOutput>\n\n```typescript\nimport { createMappingKey } from '@breadstone/archipel-platform-core';\n\nexport const PRODUCT_MAPPING_KEY = createMappingKey<IProductMappingInput, ProductResponse>('food.product');\n```\n\nThe string argument `'food.product'` is the unique registry key. Convention:\n`<domain>.<entity>` in lowercase dot-notation.\n\n## MappingService API\n\n```typescript\n// Key-based mapping (preferred)\nconst response = mappingService.map(PRODUCT_MAPPING_KEY, input);\n// \u2192 TOutput is inferred from the key, TInput is validated\n\n// Safe variant (returns undefined if not registered)\nconst maybeResponse = mappingService.tryMap(PRODUCT_MAPPING_KEY, input);\n\n// Type-based mapping (alternative)\nconst response = mappingService.mapTypes(sourceInstance, DestinationClass);\nconst responses = mappingService.mapTypesArray(sourceArray, DestinationClass);\n```\n\n## How to Create a Mapping\n\n### Step 1: Define the input interface\n\nThe input interface represents the shape of data coming from the repository query.\nProperty names MUST match the Prisma select shape exactly.\n\n```typescript\n// models/mapping-inputs/IProductMappingInput.ts\nexport interface IProductMappingInput {\n readonly id: string;\n readonly barcode: string;\n readonly name: string;\n readonly categoryId: string;\n readonly createdAt: Date;\n}\n```\n\n### Step 2: Create a branded mapping key\n\nEach key is an **exported constant** \u2014 never inline magic strings.\n\n```typescript\n// constants/MappingKeys.ts\nimport { createMappingKey } from '@breadstone/archipel-platform-core';\nimport { IProductMappingInput } from '../models/mapping-inputs/IProductMappingInput';\nimport { ProductResponse } from '../dtos/ProductResponse';\n\nexport const PRODUCT_MAPPING_KEY = createMappingKey<IProductMappingInput, ProductResponse>('food.product');\n```\n\n### Step 3: Create a mapping profile\n\nA profile extends `MappingProfileBase` and registers one or more mappings via the builder.\n\n```typescript\n// mappers/ProductMappingProfile.ts\nimport { MappingProfileBase, IMappingBuilder } from '@breadstone/archipel-platform-core';\nimport { PRODUCT_MAPPING_KEY } from '../constants/MappingKeys';\nimport { IProductMappingInput } from '../models/mapping-inputs/IProductMappingInput';\nimport { ProductResponse } from '../dtos/ProductResponse';\n\nexport class ProductMappingProfile extends MappingProfileBase {\n\n // #region Methods\n\n public configure(builder: IMappingBuilder): void {\n builder.createKeyedMap(PRODUCT_MAPPING_KEY, (input: IProductMappingInput) => {\n const response = new ProductResponse();\n response.id = input.id;\n response.barcode = input.barcode;\n response.name = input.name;\n response.categoryId = input.categoryId;\n response.createdAt = input.createdAt;\n\n return response;\n });\n }\n\n // #endregion\n\n}\n```\n\n### Step 4: Register the profile in the module\n\n```typescript\nimport { MappingModule } from '@breadstone/archipel-platform-core';\nimport { ProductMappingProfile } from './mappers/ProductMappingProfile';\n\n@Module({\n imports: [\n MappingModule.withProfiles([ProductMappingProfile]),\n ],\n})\nexport class ProductModule {}\n```\n\n### Step 5: Use in controller (NOT in service)\n\n```typescript\n@Controller('/products')\nexport class ProductController {\n\n // #region Fields\n\n private readonly _productService: ProductService;\n private readonly _mappingService: MappingService;\n\n // #endregion\n\n // #region Ctor\n\n public constructor(productService: ProductService, mappingService: MappingService) {\n this._productService = productService;\n this._mappingService = mappingService;\n }\n\n // #endregion\n\n // #region Methods\n\n @Get(':id')\n public async getProduct(@Param('id') id: string): Promise<ProductResponse> {\n const entity = await this._productService.findById(id);\n\n return this._mappingService.map(PRODUCT_MAPPING_KEY, entity);\n }\n\n @Get()\n public async listProducts(): Promise<ProductResponse[]> {\n const entities = await this._productService.findAll();\n\n return entities.map((e) => this._mappingService.map(PRODUCT_MAPPING_KEY, e));\n }\n\n // #endregion\n\n}\n```\n\n## MappingBuilder Methods\n\nThe builder supports two registration flavors:\n\n### createKeyedMap (preferred)\n\n```typescript\nbuilder.createKeyedMap(SOME_MAPPING_KEY, (input: TInput) => {\n const output = new TOutput();\n // ... map fields\n return output;\n});\n```\n\n### createMap (type-based)\n\n```typescript\nbuilder.createMap(SourceClass, DestinationClass, (source: SourceClass) => {\n const dest = new DestinationClass();\n // ... map fields\n return dest;\n});\n```\n\n## Error Handling\n\n- `MappingNotRegisteredError` \u2014 thrown when a keyed mapping is not found\n- `TypeMappingNotRegisteredError` \u2014 thrown when a type-based mapping is not found\n- Both extend `MappingError` with a machine-readable `code` field\n\n## Rules\n\n1. **Mapping keys MUST be exported constants** \u2014 never inline magic strings in services or controllers.\n2. **Services return entities, controllers map to responses** \u2014 services MUST NOT create response objects.\n3. **One mapping key per entity\u2192response pair** \u2014 use descriptive dot notation for the key string.\n4. **Input interfaces match Prisma select shape** \u2014 property names must align exactly.\n5. **Profiles extend MappingProfileBase** and are registered via `MappingModule.withProfiles()`.\n6. **Use `createKeyedMap` over `createMap`** \u2014 branded keys provide better type safety.\n7. **Mapping functions instantiate response classes** \u2014 use `new ResponseClass()` and assign fields.\n";
|
|
6
|
+
export declare const MAPPING_PATTERN_WITH_CONTEXT: (entityName: string, fields: string[], responseName: string) => string;
|