@planu/cli 0.28.0 → 0.30.0
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/dist/config/model-routing-rules.json +98 -0
- package/dist/engine/ai-cost-estimator/core.d.ts.map +1 -1
- package/dist/engine/ai-cost-estimator/core.js +2 -202
- package/dist/engine/ai-cost-estimator/core.js.map +1 -1
- package/dist/engine/ai-cost-estimator/recommender.d.ts +8 -0
- package/dist/engine/ai-cost-estimator/recommender.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/recommender.js +94 -0
- package/dist/engine/ai-cost-estimator/recommender.js.map +1 -0
- package/dist/engine/ai-cost-estimator/spec-loader.d.ts +13 -0
- package/dist/engine/ai-cost-estimator/spec-loader.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/spec-loader.js +102 -0
- package/dist/engine/ai-cost-estimator/spec-loader.js.map +1 -0
- package/dist/engine/ci-generator/planu-config.d.ts +7 -0
- package/dist/engine/ci-generator/planu-config.d.ts.map +1 -0
- package/dist/engine/ci-generator/planu-config.js +40 -0
- package/dist/engine/ci-generator/planu-config.js.map +1 -0
- package/dist/engine/ci-generator/planu-steps.d.ts +11 -0
- package/dist/engine/ci-generator/planu-steps.d.ts.map +1 -0
- package/dist/engine/ci-generator/planu-steps.js +292 -0
- package/dist/engine/ci-generator/planu-steps.js.map +1 -0
- package/dist/engine/code-transforms/transform-engine.d.ts +7 -0
- package/dist/engine/code-transforms/transform-engine.d.ts.map +1 -0
- package/dist/engine/code-transforms/transform-engine.js +67 -0
- package/dist/engine/code-transforms/transform-engine.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.js +92 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.js +83 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-types.d.ts +3 -0
- package/dist/engine/code-transforms/typescript/add-types.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-types.js +182 -0
- package/dist/engine/code-transforms/typescript/add-types.js.map +1 -0
- package/dist/engine/code-transforms/typescript/ast-utils.d.ts +38 -0
- package/dist/engine/code-transforms/typescript/ast-utils.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/ast-utils.js +90 -0
- package/dist/engine/code-transforms/typescript/ast-utils.js.map +1 -0
- package/dist/engine/code-transforms/typescript/extract-interface.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/extract-interface.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/extract-interface.js +103 -0
- package/dist/engine/code-transforms/typescript/extract-interface.js.map +1 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts +3 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.js +213 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.js.map +1 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.d.ts +8 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.js +40 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.js.map +1 -0
- package/dist/engine/mermaid/core.d.ts +18 -0
- package/dist/engine/mermaid/core.d.ts.map +1 -0
- package/dist/engine/mermaid/core.js +88 -0
- package/dist/engine/mermaid/core.js.map +1 -0
- package/dist/engine/mermaid/diagram-generators.d.ts +22 -0
- package/dist/engine/mermaid/diagram-generators.d.ts.map +1 -0
- package/dist/engine/mermaid/diagram-generators.js +139 -0
- package/dist/engine/mermaid/diagram-generators.js.map +1 -0
- package/dist/engine/mermaid/helpers.d.ts +8 -0
- package/dist/engine/mermaid/helpers.d.ts.map +1 -0
- package/dist/engine/mermaid/helpers.js +61 -0
- package/dist/engine/mermaid/helpers.js.map +1 -0
- package/dist/engine/mermaid-generator.d.ts +2 -37
- package/dist/engine/mermaid-generator.d.ts.map +1 -1
- package/dist/engine/mermaid-generator.js +4 -276
- package/dist/engine/mermaid-generator.js.map +1 -1
- package/dist/engine/model-router/complexity-analyzer.d.ts +26 -0
- package/dist/engine/model-router/complexity-analyzer.d.ts.map +1 -0
- package/dist/engine/model-router/complexity-analyzer.js +182 -0
- package/dist/engine/model-router/complexity-analyzer.js.map +1 -0
- package/dist/engine/model-router/cost-estimator.d.ts +6 -0
- package/dist/engine/model-router/cost-estimator.d.ts.map +1 -0
- package/dist/engine/model-router/cost-estimator.js +60 -0
- package/dist/engine/model-router/cost-estimator.js.map +1 -0
- package/dist/engine/model-router/historical-learner.d.ts +26 -0
- package/dist/engine/model-router/historical-learner.d.ts.map +1 -0
- package/dist/engine/model-router/historical-learner.js +91 -0
- package/dist/engine/model-router/historical-learner.js.map +1 -0
- package/dist/engine/model-router/rules-engine.d.ts +13 -0
- package/dist/engine/model-router/rules-engine.d.ts.map +1 -0
- package/dist/engine/model-router/rules-engine.js +142 -0
- package/dist/engine/model-router/rules-engine.js.map +1 -0
- package/dist/engine/spec-coverage/criteria-mapper.d.ts +1 -2
- package/dist/engine/spec-coverage/criteria-mapper.d.ts.map +1 -1
- package/dist/engine/spec-coverage/criteria-mapper.js +4 -203
- package/dist/engine/spec-coverage/criteria-mapper.js.map +1 -1
- package/dist/engine/spec-coverage/keyword-extractor.d.ts +10 -0
- package/dist/engine/spec-coverage/keyword-extractor.d.ts.map +1 -0
- package/dist/engine/spec-coverage/keyword-extractor.js +147 -0
- package/dist/engine/spec-coverage/keyword-extractor.js.map +1 -0
- package/dist/engine/spec-coverage/test-matchers.d.ts +9 -0
- package/dist/engine/spec-coverage/test-matchers.d.ts.map +1 -0
- package/dist/engine/spec-coverage/test-matchers.js +59 -0
- package/dist/engine/spec-coverage/test-matchers.js.map +1 -0
- package/dist/engine/spec-templates/catalog-extra.d.ts +1 -1
- package/dist/engine/spec-templates/catalog-extra.d.ts.map +1 -1
- package/dist/engine/spec-templates/catalog-extra.js +8 -363
- package/dist/engine/spec-templates/catalog-extra.js.map +1 -1
- package/dist/engine/spec-templates/catalog-industry.d.ts +4 -0
- package/dist/engine/spec-templates/catalog-industry.d.ts.map +1 -0
- package/dist/engine/spec-templates/catalog-industry.js +19 -0
- package/dist/engine/spec-templates/catalog-industry.js.map +1 -0
- package/dist/engine/spec-templates/catalog.d.ts +1 -1
- package/dist/engine/spec-templates/catalog.d.ts.map +1 -1
- package/dist/engine/spec-templates/catalog.js +12 -381
- package/dist/engine/spec-templates/catalog.js.map +1 -1
- package/dist/engine/spec-templates/custom-loader.d.ts +12 -0
- package/dist/engine/spec-templates/custom-loader.d.ts.map +1 -0
- package/dist/engine/spec-templates/custom-loader.js +99 -0
- package/dist/engine/spec-templates/custom-loader.js.map +1 -0
- package/dist/engine/spec-templates/index.d.ts +4 -2
- package/dist/engine/spec-templates/index.d.ts.map +1 -1
- package/dist/engine/spec-templates/index.js +4 -2
- package/dist/engine/spec-templates/index.js.map +1 -1
- package/dist/engine/spec-templates/query.d.ts +12 -4
- package/dist/engine/spec-templates/query.d.ts.map +1 -1
- package/dist/engine/spec-templates/query.js +29 -7
- package/dist/engine/spec-templates/query.js.map +1 -1
- package/dist/engine/spec-templates/renderer.d.ts +27 -2
- package/dist/engine/spec-templates/renderer.d.ts.map +1 -1
- package/dist/engine/spec-templates/renderer.js +119 -4
- package/dist/engine/spec-templates/renderer.js.map +1 -1
- package/dist/engine/spec-templates/templates-api-ui.d.ts +6 -0
- package/dist/engine/spec-templates/templates-api-ui.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-api-ui.js +215 -0
- package/dist/engine/spec-templates/templates-api-ui.js.map +1 -0
- package/dist/engine/spec-templates/templates-auth-crud.d.ts +6 -0
- package/dist/engine/spec-templates/templates-auth-crud.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-auth-crud.js +225 -0
- package/dist/engine/spec-templates/templates-auth-crud.js.map +1 -0
- package/dist/engine/spec-templates/templates-data-security.d.ts +6 -0
- package/dist/engine/spec-templates/templates-data-security.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-data-security.js +198 -0
- package/dist/engine/spec-templates/templates-data-security.js.map +1 -0
- package/dist/engine/spec-templates/templates-industry-ecom.d.ts +6 -0
- package/dist/engine/spec-templates/templates-industry-ecom.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-industry-ecom.js +209 -0
- package/dist/engine/spec-templates/templates-industry-ecom.js.map +1 -0
- package/dist/engine/spec-templates/templates-industry-fintech.d.ts +8 -0
- package/dist/engine/spec-templates/templates-industry-fintech.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-industry-fintech.js +350 -0
- package/dist/engine/spec-templates/templates-industry-fintech.js.map +1 -0
- package/dist/engine/spec-templates/templates-industry-health-ecom.d.ts +3 -0
- package/dist/engine/spec-templates/templates-industry-health-ecom.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-industry-health-ecom.js +5 -0
- package/dist/engine/spec-templates/templates-industry-health-ecom.js.map +1 -0
- package/dist/engine/spec-templates/templates-industry-health.d.ts +6 -0
- package/dist/engine/spec-templates/templates-industry-health.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-industry-health.js +208 -0
- package/dist/engine/spec-templates/templates-industry-health.js.map +1 -0
- package/dist/engine/spec-templates/templates-industry-saas.d.ts +8 -0
- package/dist/engine/spec-templates/templates-industry-saas.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-industry-saas.js +323 -0
- package/dist/engine/spec-templates/templates-industry-saas.js.map +1 -0
- package/dist/engine/spec-templates/templates-perf-integration.d.ts +6 -0
- package/dist/engine/spec-templates/templates-perf-integration.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-perf-integration.js +226 -0
- package/dist/engine/spec-templates/templates-perf-integration.js.map +1 -0
- package/dist/engine/vector-store/hnsw.d.ts +37 -0
- package/dist/engine/vector-store/hnsw.d.ts.map +1 -0
- package/dist/engine/vector-store/hnsw.js +294 -0
- package/dist/engine/vector-store/hnsw.js.map +1 -0
- package/dist/engine/vector-store/similarity.d.ts +21 -0
- package/dist/engine/vector-store/similarity.d.ts.map +1 -0
- package/dist/engine/vector-store/similarity.js +86 -0
- package/dist/engine/vector-store/similarity.js.map +1 -0
- package/dist/engine/vector-store/tfidf.d.ts +35 -0
- package/dist/engine/vector-store/tfidf.d.ts.map +1 -0
- package/dist/engine/vector-store/tfidf.js +255 -0
- package/dist/engine/vector-store/tfidf.js.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/vector-store/backend-factory.d.ts +9 -0
- package/dist/storage/vector-store/backend-factory.d.ts.map +1 -0
- package/dist/storage/vector-store/backend-factory.js +33 -0
- package/dist/storage/vector-store/backend-factory.js.map +1 -0
- package/dist/storage/vector-store/json-fallback.d.ts +21 -0
- package/dist/storage/vector-store/json-fallback.d.ts.map +1 -0
- package/dist/storage/vector-store/json-fallback.js +85 -0
- package/dist/storage/vector-store/json-fallback.js.map +1 -0
- package/dist/storage/vector-store/migrator.d.ts +10 -0
- package/dist/storage/vector-store/migrator.d.ts.map +1 -0
- package/dist/storage/vector-store/migrator.js +139 -0
- package/dist/storage/vector-store/migrator.js.map +1 -0
- package/dist/storage/vector-store/sqlite-adapter.d.ts +28 -0
- package/dist/storage/vector-store/sqlite-adapter.d.ts.map +1 -0
- package/dist/storage/vector-store/sqlite-adapter.js +142 -0
- package/dist/storage/vector-store/sqlite-adapter.js.map +1 -0
- package/dist/tools/ci-planu-handler.d.ts +8 -0
- package/dist/tools/ci-planu-handler.d.ts.map +1 -0
- package/dist/tools/ci-planu-handler.js +44 -0
- package/dist/tools/ci-planu-handler.js.map +1 -0
- package/dist/tools/create-spec/constitution-validator.d.ts +4 -0
- package/dist/tools/create-spec/constitution-validator.d.ts.map +1 -0
- package/dist/tools/create-spec/constitution-validator.js +37 -0
- package/dist/tools/create-spec/constitution-validator.js.map +1 -0
- package/dist/tools/create-spec/post-creation.d.ts +11 -0
- package/dist/tools/create-spec/post-creation.d.ts.map +1 -0
- package/dist/tools/create-spec/post-creation.js +48 -0
- package/dist/tools/create-spec/post-creation.js.map +1 -0
- package/dist/tools/create-spec/spec-builder.d.ts +14 -0
- package/dist/tools/create-spec/spec-builder.d.ts.map +1 -0
- package/dist/tools/create-spec/spec-builder.js +131 -0
- package/dist/tools/create-spec/spec-builder.js.map +1 -0
- package/dist/tools/create-spec.d.ts.map +1 -1
- package/dist/tools/create-spec.js +42 -172
- package/dist/tools/create-spec.js.map +1 -1
- package/dist/tools/init-project/handler.d.ts.map +1 -1
- package/dist/tools/init-project/handler.js +24 -159
- package/dist/tools/init-project/handler.js.map +1 -1
- package/dist/tools/init-project/result-builder.d.ts +4 -0
- package/dist/tools/init-project/result-builder.d.ts.map +1 -0
- package/dist/tools/init-project/result-builder.js +150 -0
- package/dist/tools/init-project/result-builder.js.map +1 -0
- package/dist/tools/learn.d.ts.map +1 -1
- package/dist/tools/learn.js +67 -14
- package/dist/tools/learn.js.map +1 -1
- package/dist/tools/recommend-model-handler.d.ts +8 -0
- package/dist/tools/recommend-model-handler.d.ts.map +1 -0
- package/dist/tools/recommend-model-handler.js +65 -0
- package/dist/tools/recommend-model-handler.js.map +1 -0
- package/dist/tools/register-ci-tools.d.ts.map +1 -1
- package/dist/tools/register-ci-tools.js +36 -0
- package/dist/tools/register-ci-tools.js.map +1 -1
- package/dist/tools/register-model-tools.d.ts +3 -0
- package/dist/tools/register-model-tools.d.ts.map +1 -0
- package/dist/tools/register-model-tools.js +50 -0
- package/dist/tools/register-model-tools.js.map +1 -0
- package/dist/tools/register-search-tools.d.ts +7 -0
- package/dist/tools/register-search-tools.d.ts.map +1 -0
- package/dist/tools/register-search-tools.js +34 -0
- package/dist/tools/register-search-tools.js.map +1 -0
- package/dist/tools/register-template-tools.d.ts.map +1 -1
- package/dist/tools/register-template-tools.js +21 -8
- package/dist/tools/register-template-tools.js.map +1 -1
- package/dist/tools/register-transform-tools.d.ts +3 -0
- package/dist/tools/register-transform-tools.d.ts.map +1 -0
- package/dist/tools/register-transform-tools.js +29 -0
- package/dist/tools/register-transform-tools.js.map +1 -0
- package/dist/tools/semantic-search-handler.d.ts +7 -0
- package/dist/tools/semantic-search-handler.d.ts.map +1 -0
- package/dist/tools/semantic-search-handler.js +72 -0
- package/dist/tools/semantic-search-handler.js.map +1 -0
- package/dist/tools/spec-templates.d.ts +1 -1
- package/dist/tools/spec-templates.d.ts.map +1 -1
- package/dist/tools/spec-templates.js +20 -6
- package/dist/tools/spec-templates.js.map +1 -1
- package/dist/tools/transform-code-handler.d.ts +7 -0
- package/dist/tools/transform-code-handler.d.ts.map +1 -0
- package/dist/tools/transform-code-handler.js +58 -0
- package/dist/tools/transform-code-handler.js.map +1 -0
- package/dist/types/advanced-framework.d.ts +47 -0
- package/dist/types/advanced-framework.d.ts.map +1 -0
- package/dist/types/advanced-framework.js +3 -0
- package/dist/types/advanced-framework.js.map +1 -0
- package/dist/types/ci.d.ts +51 -0
- package/dist/types/ci.d.ts.map +1 -1
- package/dist/types/code-transforms.d.ts +114 -0
- package/dist/types/code-transforms.d.ts.map +1 -0
- package/dist/types/code-transforms.js +11 -0
- package/dist/types/code-transforms.js.map +1 -0
- package/dist/types/css-framework.d.ts +110 -0
- package/dist/types/css-framework.d.ts.map +1 -0
- package/dist/types/css-framework.js +3 -0
- package/dist/types/css-framework.js.map +1 -0
- package/dist/types/dashboard.d.ts +77 -0
- package/dist/types/dashboard.d.ts.map +1 -0
- package/dist/types/dashboard.js +2 -0
- package/dist/types/dashboard.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/model-routing.d.ts +127 -0
- package/dist/types/model-routing.d.ts.map +1 -0
- package/dist/types/model-routing.js +3 -0
- package/dist/types/model-routing.js.map +1 -0
- package/dist/types/project/core.d.ts +46 -5
- package/dist/types/project/core.d.ts.map +1 -1
- package/dist/types/spec/core.d.ts +28 -1
- package/dist/types/spec/core.d.ts.map +1 -1
- package/dist/types/spec/inputs.d.ts +1 -6
- package/dist/types/spec/inputs.d.ts.map +1 -1
- package/dist/types/spec-templates.d.ts +51 -1
- package/dist/types/spec-templates.d.ts.map +1 -1
- package/dist/types/ui.d.ts +3 -231
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/types/ui.js +7 -1
- package/dist/types/ui.js.map +1 -1
- package/dist/types/vector-store.d.ts +144 -0
- package/dist/types/vector-store.d.ts.map +1 -0
- package/dist/types/vector-store.js +3 -0
- package/dist/types/vector-store.js.map +1 -0
- package/package.json +1 -1
- package/src/config/model-routing-rules.json +98 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// engine/spec-templates/templates-industry-saas.ts — SaaS industry templates.
|
|
2
|
+
// AC-04: Templates by industry — SaaS vertical (multi-tenant, billing, RBAC).
|
|
3
|
+
/** SaaS multi-tenant template. */
|
|
4
|
+
export const SAAS_MULTI_TENANT_TEMPLATE = {
|
|
5
|
+
id: 'saas-multi-tenant',
|
|
6
|
+
name: 'Arquitectura multi-tenant',
|
|
7
|
+
category: 'industry',
|
|
8
|
+
subcategory: 'saas',
|
|
9
|
+
description: 'Aislamiento de datos por tenant, subdominios y configuracion por tenant.',
|
|
10
|
+
tags: ['saas', 'multi-tenant', 'isolation', 'tenancy'],
|
|
11
|
+
complexityScore: 'XL',
|
|
12
|
+
estimationBase: {
|
|
13
|
+
hoursMin: 80,
|
|
14
|
+
hoursMax: 160,
|
|
15
|
+
notes: 'Arquitectura fundamental que impacta todas las capas',
|
|
16
|
+
},
|
|
17
|
+
criteria: [
|
|
18
|
+
{ id: 'AC-1', title: 'Aislamiento de datos', required: true },
|
|
19
|
+
{ id: 'AC-2', title: 'Resolucion de tenant', required: true },
|
|
20
|
+
{ id: 'AC-3', title: 'Configuracion por tenant', required: true },
|
|
21
|
+
{ id: 'AC-4', title: 'Onboarding de tenant', required: true },
|
|
22
|
+
{ id: 'AC-5', title: 'Limites por tenant', required: true },
|
|
23
|
+
{ id: 'AC-6', title: 'Operaciones cross-tenant', required: false },
|
|
24
|
+
],
|
|
25
|
+
variables: [
|
|
26
|
+
{
|
|
27
|
+
key: 'PlatformName',
|
|
28
|
+
label: 'Nombre de la plataforma',
|
|
29
|
+
description: 'Nombre de la plataforma SaaS',
|
|
30
|
+
example: 'CloudApp',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
huTemplate: `# HU: Multi-Tenant — {{PlatformName}}
|
|
35
|
+
|
|
36
|
+
## Historia de Usuario
|
|
37
|
+
Como operador de {{PlatformName}}, quiero que cada tenant tenga sus datos aislados y su configuracion independiente para ofrecer un servicio seguro y personalizable.
|
|
38
|
+
|
|
39
|
+
## Criterios de Aceptacion
|
|
40
|
+
|
|
41
|
+
### AC-1: Aislamiento de datos
|
|
42
|
+
- [ ] Los datos de cada tenant son inaccesibles para otros tenants
|
|
43
|
+
- [ ] Las consultas a base de datos filtran por tenant automaticamente
|
|
44
|
+
- [ ] No existe ruta de acceso que permita cross-tenant sin autorizacion explicita
|
|
45
|
+
- [ ] Las pruebas verifican que el aislamiento funciona correctamente
|
|
46
|
+
|
|
47
|
+
### AC-2: Resolucion de tenant
|
|
48
|
+
- [ ] El tenant se resuelve desde subdominio, header o token segun la estrategia elegida
|
|
49
|
+
- [ ] La resolucion es transparente para el codigo de negocio
|
|
50
|
+
- [ ] Solicitudes sin tenant valido son rechazadas con error claro
|
|
51
|
+
|
|
52
|
+
### AC-3: Configuracion por tenant
|
|
53
|
+
- [ ] Cada tenant puede personalizar branding (logo, colores, nombre)
|
|
54
|
+
- [ ] Las configuraciones de funcionalidad son independientes por tenant
|
|
55
|
+
- [ ] Los valores por defecto se heredan de la configuracion global
|
|
56
|
+
|
|
57
|
+
### AC-4: Onboarding de tenant
|
|
58
|
+
- [ ] El alta de un nuevo tenant es automatizada (no requiere intervencion manual)
|
|
59
|
+
- [ ] Se provisionan los recursos necesarios (schema/namespace/bucket)
|
|
60
|
+
- [ ] El administrador del tenant recibe credenciales de acceso
|
|
61
|
+
|
|
62
|
+
### AC-5: Limites por tenant
|
|
63
|
+
- [ ] Cada tenant tiene limites de uso configurables (usuarios, storage, API calls)
|
|
64
|
+
- [ ] Se notifica al tenant cuando se acerca a sus limites
|
|
65
|
+
- [ ] Exceder limites bloquea operaciones nuevas (no las existentes)
|
|
66
|
+
|
|
67
|
+
### AC-6: Operaciones cross-tenant (solo para superadmin)
|
|
68
|
+
- [ ] El superadmin puede consultar metricas agregadas de todos los tenants
|
|
69
|
+
- [ ] Las operaciones de mantenimiento pueden ejecutarse por tenant o globalmente
|
|
70
|
+
`,
|
|
71
|
+
fichaTecnicaTemplate: `# FICHA TÉCNICA: Multi-Tenant — {{PlatformName}}
|
|
72
|
+
|
|
73
|
+
## Archivos Afectados
|
|
74
|
+
- tenancy/resolver
|
|
75
|
+
- tenancy/isolation-middleware
|
|
76
|
+
- tenancy/config-manager
|
|
77
|
+
- tenancy/onboarding
|
|
78
|
+
- tenancy/limits
|
|
79
|
+
|
|
80
|
+
## Tipos / Entidades
|
|
81
|
+
- \`Tenant\`: id, name, slug, config, limits, createdAt
|
|
82
|
+
- \`TenantConfig\`: branding, features, defaults
|
|
83
|
+
- \`TenantLimit\`: type, maxValue, currentValue
|
|
84
|
+
|
|
85
|
+
## Riesgos
|
|
86
|
+
- Fuga de datos entre tenants → filtrado automatico + tests de aislamiento
|
|
87
|
+
- Onboarding lento → provisionamiento asincronico con status tracking
|
|
88
|
+
- Limites no respetados → middleware de verificacion en cada request
|
|
89
|
+
|
|
90
|
+
## Estimacion
|
|
91
|
+
- Dev: 80–160 horas
|
|
92
|
+
- Review: 16–32 horas
|
|
93
|
+
- Dificultad: 5/5
|
|
94
|
+
`,
|
|
95
|
+
progressTemplate: `# PROGRESS: Multi-Tenant — {{PlatformName}}
|
|
96
|
+
|
|
97
|
+
## Estado: borrador
|
|
98
|
+
|
|
99
|
+
## Criterios
|
|
100
|
+
- [ ] AC-1: Aislamiento de datos
|
|
101
|
+
- [ ] AC-2: Resolucion de tenant
|
|
102
|
+
- [ ] AC-3: Configuracion por tenant
|
|
103
|
+
- [ ] AC-4: Onboarding de tenant
|
|
104
|
+
- [ ] AC-5: Limites por tenant
|
|
105
|
+
- [ ] AC-6: Operaciones cross-tenant
|
|
106
|
+
`,
|
|
107
|
+
};
|
|
108
|
+
/** SaaS billing and subscriptions template. */
|
|
109
|
+
export const SAAS_BILLING_TEMPLATE = {
|
|
110
|
+
id: 'saas-billing',
|
|
111
|
+
name: 'Facturacion y suscripciones',
|
|
112
|
+
category: 'industry',
|
|
113
|
+
subcategory: 'saas',
|
|
114
|
+
description: 'Planes de suscripcion, upgrades, facturacion PDF y webhooks de pago.',
|
|
115
|
+
tags: ['saas', 'billing', 'subscriptions', 'invoices', 'payments'],
|
|
116
|
+
complexityScore: 'L',
|
|
117
|
+
estimationBase: {
|
|
118
|
+
hoursMin: 40,
|
|
119
|
+
hoursMax: 80,
|
|
120
|
+
notes: 'Incluye integracion con pasarela de pago y generacion de facturas',
|
|
121
|
+
},
|
|
122
|
+
criteria: [
|
|
123
|
+
{ id: 'AC-1', title: 'Planes de suscripcion', required: true },
|
|
124
|
+
{ id: 'AC-2', title: 'Upgrades y downgrades', required: true },
|
|
125
|
+
{ id: 'AC-3', title: 'Facturacion', required: true },
|
|
126
|
+
{ id: 'AC-4', title: 'Webhooks de pago', required: true },
|
|
127
|
+
{ id: 'AC-5', title: 'Periodo de prueba', required: false },
|
|
128
|
+
{ id: 'AC-6', title: 'Metricas de revenue', required: false },
|
|
129
|
+
],
|
|
130
|
+
variables: [
|
|
131
|
+
{
|
|
132
|
+
key: 'PlatformName',
|
|
133
|
+
label: 'Nombre de la plataforma',
|
|
134
|
+
description: 'Nombre de la plataforma SaaS',
|
|
135
|
+
example: 'CloudApp',
|
|
136
|
+
required: true,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
huTemplate: `# HU: Facturacion y Suscripciones — {{PlatformName}}
|
|
140
|
+
|
|
141
|
+
## Historia de Usuario
|
|
142
|
+
Como usuario de {{PlatformName}}, quiero gestionar mi suscripcion y recibir facturas para mantener mi cuenta al dia.
|
|
143
|
+
|
|
144
|
+
## Criterios de Aceptacion
|
|
145
|
+
|
|
146
|
+
### AC-1: Planes de suscripcion
|
|
147
|
+
- [ ] El sistema define planes con nombre, precio, ciclo de facturacion y features incluidas
|
|
148
|
+
- [ ] Los planes son configurables sin despliegue (admin dashboard o config)
|
|
149
|
+
- [ ] Se soportan planes mensuales y anuales como minimo
|
|
150
|
+
- [ ] Los precios soportan multiples monedas
|
|
151
|
+
|
|
152
|
+
### AC-2: Upgrades y downgrades
|
|
153
|
+
- [ ] El usuario puede cambiar de plan en cualquier momento
|
|
154
|
+
- [ ] Los upgrades se aplican inmediatamente con prorrateo
|
|
155
|
+
- [ ] Los downgrades se aplican al final del periodo de facturacion actual
|
|
156
|
+
- [ ] Se notifica al usuario del impacto del cambio antes de confirmar
|
|
157
|
+
|
|
158
|
+
### AC-3: Facturacion
|
|
159
|
+
- [ ] Se genera factura automatica en cada ciclo de facturacion
|
|
160
|
+
- [ ] La factura es descargable en PDF con datos fiscales
|
|
161
|
+
- [ ] El historial de facturas es accesible para el usuario
|
|
162
|
+
- [ ] Los pagos fallidos generan reintentos con notificacion al usuario
|
|
163
|
+
|
|
164
|
+
### AC-4: Webhooks de pago
|
|
165
|
+
- [ ] Los eventos de pago del proveedor se reciben y procesan via webhook
|
|
166
|
+
- [ ] Los webhooks validan firma/autenticidad antes de procesar
|
|
167
|
+
- [ ] El procesamiento es idempotente (replay-safe)
|
|
168
|
+
- [ ] Los eventos fallidos se reintentan con backoff
|
|
169
|
+
|
|
170
|
+
### AC-5: Periodo de prueba
|
|
171
|
+
- [ ] Los nuevos usuarios pueden acceder a un periodo de prueba configurable
|
|
172
|
+
- [ ] Se notifica antes del fin del trial con opcion de convertir
|
|
173
|
+
- [ ] Al expirar el trial, se limita el acceso sin perder datos
|
|
174
|
+
|
|
175
|
+
### AC-6: Metricas de revenue
|
|
176
|
+
- [ ] MRR (Monthly Recurring Revenue) calculado automaticamente
|
|
177
|
+
- [ ] Churn rate visible en dashboard de admin
|
|
178
|
+
- [ ] Cohort analysis por mes de registro
|
|
179
|
+
`,
|
|
180
|
+
fichaTecnicaTemplate: `# FICHA TÉCNICA: Facturacion — {{PlatformName}}
|
|
181
|
+
|
|
182
|
+
## Archivos Afectados
|
|
183
|
+
- billing/plans
|
|
184
|
+
- billing/subscriptions
|
|
185
|
+
- billing/invoices
|
|
186
|
+
- billing/webhook-handler
|
|
187
|
+
- billing/trial
|
|
188
|
+
|
|
189
|
+
## Tipos / Entidades
|
|
190
|
+
- \`Plan\`: id, name, price, currency, interval, features[]
|
|
191
|
+
- \`Subscription\`: userId, planId, status, startedAt, expiresAt
|
|
192
|
+
- \`Invoice\`: id, subscriptionId, amount, currency, paidAt, pdfUrl
|
|
193
|
+
|
|
194
|
+
## Riesgos
|
|
195
|
+
- Doble cobro → idempotencia en webhook processing
|
|
196
|
+
- Factura incorrecta → validacion cruzada con proveedor
|
|
197
|
+
- Trial abuse → limitar a un trial por usuario/email
|
|
198
|
+
|
|
199
|
+
## Estimacion
|
|
200
|
+
- Dev: 40–80 horas
|
|
201
|
+
- Review: 8–16 horas
|
|
202
|
+
- Dificultad: 4/5
|
|
203
|
+
`,
|
|
204
|
+
progressTemplate: `# PROGRESS: Facturacion — {{PlatformName}}
|
|
205
|
+
|
|
206
|
+
## Estado: borrador
|
|
207
|
+
|
|
208
|
+
## Criterios
|
|
209
|
+
- [ ] AC-1: Planes de suscripcion
|
|
210
|
+
- [ ] AC-2: Upgrades y downgrades
|
|
211
|
+
- [ ] AC-3: Facturacion
|
|
212
|
+
- [ ] AC-4: Webhooks de pago
|
|
213
|
+
- [ ] AC-5: Periodo de prueba
|
|
214
|
+
- [ ] AC-6: Metricas de revenue
|
|
215
|
+
`,
|
|
216
|
+
};
|
|
217
|
+
/** SaaS RBAC template. */
|
|
218
|
+
export const SAAS_ROLES_TEMPLATE = {
|
|
219
|
+
id: 'saas-roles',
|
|
220
|
+
name: 'Control de acceso basado en roles (RBAC)',
|
|
221
|
+
category: 'industry',
|
|
222
|
+
subcategory: 'saas',
|
|
223
|
+
description: 'Permisos granulares, herencia de roles y auditoria de acceso.',
|
|
224
|
+
tags: ['saas', 'rbac', 'permissions', 'roles', 'access-control'],
|
|
225
|
+
complexityScore: 'M',
|
|
226
|
+
estimationBase: {
|
|
227
|
+
hoursMin: 24,
|
|
228
|
+
hoursMax: 48,
|
|
229
|
+
notes: 'Incluye herencia de roles y auditoria de acceso',
|
|
230
|
+
},
|
|
231
|
+
criteria: [
|
|
232
|
+
{ id: 'AC-1', title: 'Definicion de roles', required: true },
|
|
233
|
+
{ id: 'AC-2', title: 'Permisos granulares', required: true },
|
|
234
|
+
{ id: 'AC-3', title: 'Herencia de roles', required: false },
|
|
235
|
+
{ id: 'AC-4', title: 'Asignacion de roles', required: true },
|
|
236
|
+
{ id: 'AC-5', title: 'Verificacion de permisos', required: true },
|
|
237
|
+
{ id: 'AC-6', title: 'Auditoria de acceso', required: true },
|
|
238
|
+
],
|
|
239
|
+
variables: [
|
|
240
|
+
{
|
|
241
|
+
key: 'PlatformName',
|
|
242
|
+
label: 'Nombre de la plataforma',
|
|
243
|
+
description: 'Nombre de la plataforma SaaS',
|
|
244
|
+
example: 'CloudApp',
|
|
245
|
+
required: true,
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
huTemplate: `# HU: RBAC — {{PlatformName}}
|
|
249
|
+
|
|
250
|
+
## Historia de Usuario
|
|
251
|
+
Como administrador de {{PlatformName}}, quiero asignar roles y permisos a los usuarios para controlar que acciones puede realizar cada uno.
|
|
252
|
+
|
|
253
|
+
## Criterios de Aceptacion
|
|
254
|
+
|
|
255
|
+
### AC-1: Definicion de roles
|
|
256
|
+
- [ ] Los roles se definen con nombre, descripcion y conjunto de permisos
|
|
257
|
+
- [ ] Existen roles predefinidos (admin, editor, viewer) configurables
|
|
258
|
+
- [ ] Se pueden crear roles personalizados
|
|
259
|
+
- [ ] Los roles se gestionan por tenant (no globales)
|
|
260
|
+
|
|
261
|
+
### AC-2: Permisos granulares
|
|
262
|
+
- [ ] Los permisos se definen como pares recurso:accion (e.g. "users:create")
|
|
263
|
+
- [ ] Se soportan wildcards (e.g. "users:*" para todas las acciones sobre usuarios)
|
|
264
|
+
- [ ] Los permisos nuevos se agregan sin redeploy (configuracion)
|
|
265
|
+
|
|
266
|
+
### AC-3: Herencia de roles
|
|
267
|
+
- [ ] Un rol puede heredar permisos de otro rol padre
|
|
268
|
+
- [ ] La herencia es transitiva (admin hereda de editor que hereda de viewer)
|
|
269
|
+
- [ ] Los permisos heredados pueden ser revocados explicitamente
|
|
270
|
+
|
|
271
|
+
### AC-4: Asignacion de roles
|
|
272
|
+
- [ ] Los administradores pueden asignar/revocar roles a usuarios
|
|
273
|
+
- [ ] Un usuario puede tener multiples roles (los permisos se combinan)
|
|
274
|
+
- [ ] Los cambios de rol se aplican inmediatamente (sin requerir re-login)
|
|
275
|
+
|
|
276
|
+
### AC-5: Verificacion de permisos
|
|
277
|
+
- [ ] Toda ruta/accion verifica permisos antes de ejecutar
|
|
278
|
+
- [ ] La verificacion es eficiente (cache en memoria, no DB por request)
|
|
279
|
+
- [ ] Los permisos denegados retornan 403 con mensaje claro
|
|
280
|
+
|
|
281
|
+
### AC-6: Auditoria de acceso
|
|
282
|
+
- [ ] Los cambios de roles y permisos se registran con timestamp y actor
|
|
283
|
+
- [ ] Los accesos denegados se registran para analisis de seguridad
|
|
284
|
+
- [ ] El registro de auditoria es consultable por admin
|
|
285
|
+
`,
|
|
286
|
+
fichaTecnicaTemplate: `# FICHA TÉCNICA: RBAC — {{PlatformName}}
|
|
287
|
+
|
|
288
|
+
## Archivos Afectados
|
|
289
|
+
- rbac/roles
|
|
290
|
+
- rbac/permissions
|
|
291
|
+
- rbac/assignment
|
|
292
|
+
- rbac/middleware (permission check)
|
|
293
|
+
- rbac/audit-log
|
|
294
|
+
|
|
295
|
+
## Tipos / Entidades
|
|
296
|
+
- \`Role\`: id, name, permissions[], parentRoleId
|
|
297
|
+
- \`Permission\`: resource, action, granted
|
|
298
|
+
- \`RoleAssignment\`: userId, roleId, assignedBy, assignedAt
|
|
299
|
+
|
|
300
|
+
## Riesgos
|
|
301
|
+
- Escalacion de privilegios → tests de aislamiento de permisos
|
|
302
|
+
- Cache de permisos desactualizado → invalidacion al cambiar roles
|
|
303
|
+
- Herencia circular → validacion al definir roles padre
|
|
304
|
+
|
|
305
|
+
## Estimacion
|
|
306
|
+
- Dev: 24–48 horas
|
|
307
|
+
- Review: 4–8 horas
|
|
308
|
+
- Dificultad: 3/5
|
|
309
|
+
`,
|
|
310
|
+
progressTemplate: `# PROGRESS: RBAC — {{PlatformName}}
|
|
311
|
+
|
|
312
|
+
## Estado: borrador
|
|
313
|
+
|
|
314
|
+
## Criterios
|
|
315
|
+
- [ ] AC-1: Definicion de roles
|
|
316
|
+
- [ ] AC-2: Permisos granulares
|
|
317
|
+
- [ ] AC-3: Herencia de roles
|
|
318
|
+
- [ ] AC-4: Asignacion de roles
|
|
319
|
+
- [ ] AC-5: Verificacion de permisos
|
|
320
|
+
- [ ] AC-6: Auditoria de acceso
|
|
321
|
+
`,
|
|
322
|
+
};
|
|
323
|
+
//# sourceMappingURL=templates-industry-saas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates-industry-saas.js","sourceRoot":"","sources":["../../../src/engine/spec-templates/templates-industry-saas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SpecTemplateEntry } from '../../types/spec-templates.js';
|
|
2
|
+
/** Performance optimization spec template. */
|
|
3
|
+
export declare const PERFORMANCE_OPTIMIZATION_TEMPLATE: SpecTemplateEntry;
|
|
4
|
+
/** Third-party integration spec template. */
|
|
5
|
+
export declare const THIRD_PARTY_INTEGRATION_TEMPLATE: SpecTemplateEntry;
|
|
6
|
+
//# sourceMappingURL=templates-perf-integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates-perf-integration.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-templates/templates-perf-integration.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,8CAA8C;AAC9C,eAAO,MAAM,iCAAiC,EAAE,iBA+G/C,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,gCAAgC,EAAE,iBA4G9C,CAAC"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// engine/spec-templates/templates-perf-integration.ts — Performance + third-party integration templates.
|
|
2
|
+
// Extracted from catalog-extra.ts to keep file sizes within limits.
|
|
3
|
+
/** Performance optimization spec template. */
|
|
4
|
+
export const PERFORMANCE_OPTIMIZATION_TEMPLATE = {
|
|
5
|
+
id: 'performance-optimization',
|
|
6
|
+
name: 'Performance Optimization',
|
|
7
|
+
category: 'performance',
|
|
8
|
+
description: 'Measurable performance improvements with before/after benchmarks.',
|
|
9
|
+
tags: ['performance', 'optimization', 'caching', 'benchmarks'],
|
|
10
|
+
complexityScore: 'L',
|
|
11
|
+
estimationBase: {
|
|
12
|
+
hoursMin: 16,
|
|
13
|
+
hoursMax: 60,
|
|
14
|
+
notes: 'Highly variable by root cause; includes benchmarking setup',
|
|
15
|
+
},
|
|
16
|
+
criteria: [
|
|
17
|
+
{ id: 'AC-1', title: 'Baseline measurement', required: true },
|
|
18
|
+
{ id: 'AC-2', title: 'Optimization implementation', required: true },
|
|
19
|
+
{ id: 'AC-3', title: 'Cache strategy', required: false },
|
|
20
|
+
{ id: 'AC-4', title: 'Validation', required: true },
|
|
21
|
+
{ id: 'AC-5', title: 'Observability', required: false },
|
|
22
|
+
],
|
|
23
|
+
variables: [
|
|
24
|
+
{
|
|
25
|
+
key: 'TargetArea',
|
|
26
|
+
label: 'Target area',
|
|
27
|
+
description: 'The specific area to optimize (e.g. API response time, DB queries)',
|
|
28
|
+
example: 'API response time',
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'CurrentBaseline',
|
|
33
|
+
label: 'Current baseline',
|
|
34
|
+
description: 'Current measured performance metric',
|
|
35
|
+
example: 'P95 latency: 800ms',
|
|
36
|
+
required: false,
|
|
37
|
+
defaultValue: 'TBD — measure before starting',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'TargetGoal',
|
|
41
|
+
label: 'Target goal',
|
|
42
|
+
description: 'Desired performance metric after optimization',
|
|
43
|
+
example: 'P95 latency: < 200ms',
|
|
44
|
+
required: false,
|
|
45
|
+
defaultValue: 'TBD — define after baseline measurement',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
huTemplate: `# HU: Performance Optimization — {{TargetArea}}
|
|
49
|
+
|
|
50
|
+
## User Story
|
|
51
|
+
As a user, I want {{TargetArea}} to be faster so that the application feels responsive.
|
|
52
|
+
|
|
53
|
+
## Baseline
|
|
54
|
+
- Current: {{CurrentBaseline}}
|
|
55
|
+
- Target: {{TargetGoal}}
|
|
56
|
+
|
|
57
|
+
## Acceptance Criteria
|
|
58
|
+
|
|
59
|
+
### AC-1: Baseline measurement
|
|
60
|
+
- [ ] Benchmark suite established before any changes
|
|
61
|
+
- [ ] Metrics captured: P50, P95, P99 latency, throughput, error rate
|
|
62
|
+
- [ ] Benchmark results stored for comparison
|
|
63
|
+
|
|
64
|
+
### AC-2: Optimization implementation
|
|
65
|
+
- [ ] Root cause of performance issue identified and documented
|
|
66
|
+
- [ ] Optimization applied at the correct layer
|
|
67
|
+
- [ ] No correctness regression introduced by optimization
|
|
68
|
+
|
|
69
|
+
### AC-3: Cache strategy (if applicable)
|
|
70
|
+
- [ ] Cache invalidation strategy defined
|
|
71
|
+
- [ ] Cache hit rate monitored
|
|
72
|
+
- [ ] Cache warm-up procedure documented
|
|
73
|
+
|
|
74
|
+
### AC-4: Validation
|
|
75
|
+
- [ ] Post-optimization benchmark shows improvement vs baseline
|
|
76
|
+
- [ ] Target goal reached or documented with explanation if not
|
|
77
|
+
- [ ] Load test confirms improvement holds under concurrent traffic
|
|
78
|
+
|
|
79
|
+
### AC-5: Observability
|
|
80
|
+
- [ ] Performance metrics added to dashboard
|
|
81
|
+
- [ ] Regression alert configured (auto-detect if P95 degrades)
|
|
82
|
+
`,
|
|
83
|
+
fichaTecnicaTemplate: `# FICHA TÉCNICA: Performance Optimization — {{TargetArea}}
|
|
84
|
+
|
|
85
|
+
## Affected Files
|
|
86
|
+
- (determined during root-cause analysis)
|
|
87
|
+
- monitoring/dashboards/{{TargetArea}}
|
|
88
|
+
- benchmarks/{{TargetArea}}
|
|
89
|
+
|
|
90
|
+
## Types / Entities
|
|
91
|
+
- \`BenchmarkResult\`: timestamp, p50, p95, p99, throughput, errorRate
|
|
92
|
+
- \`CacheEntry\` (if caching): key, value, ttl, hitCount
|
|
93
|
+
|
|
94
|
+
## Risks
|
|
95
|
+
- Optimization that breaks correctness → benchmark must include correctness tests
|
|
96
|
+
- Cache inconsistency → strong consistency tests required
|
|
97
|
+
- Performance regression after unrelated change → regression alert required
|
|
98
|
+
|
|
99
|
+
## Estimation (rough)
|
|
100
|
+
- Dev: 4–20 hours (highly variable by root cause)
|
|
101
|
+
- Review: 2–4 hours
|
|
102
|
+
- Difficulty: 3–4/5
|
|
103
|
+
`,
|
|
104
|
+
progressTemplate: `# PROGRESS: Performance Optimization — {{TargetArea}}
|
|
105
|
+
|
|
106
|
+
## Status: draft
|
|
107
|
+
|
|
108
|
+
## Criteria
|
|
109
|
+
- [ ] AC-1: Baseline measurement
|
|
110
|
+
- [ ] AC-2: Optimization implementation
|
|
111
|
+
- [ ] AC-3: Cache strategy
|
|
112
|
+
- [ ] AC-4: Validation
|
|
113
|
+
- [ ] AC-5: Observability
|
|
114
|
+
`,
|
|
115
|
+
};
|
|
116
|
+
/** Third-party integration spec template. */
|
|
117
|
+
export const THIRD_PARTY_INTEGRATION_TEMPLATE = {
|
|
118
|
+
id: 'third-party-integration',
|
|
119
|
+
name: 'Third-Party Integration',
|
|
120
|
+
category: 'integration',
|
|
121
|
+
description: 'Integrating with an external service (payment, email, SMS, CRM, etc.).',
|
|
122
|
+
tags: ['integration', 'external', 'api', 'webhook'],
|
|
123
|
+
complexityScore: 'M',
|
|
124
|
+
estimationBase: {
|
|
125
|
+
hoursMin: 16,
|
|
126
|
+
hoursMax: 40,
|
|
127
|
+
notes: 'Includes webhook handling and circuit breaker setup',
|
|
128
|
+
},
|
|
129
|
+
criteria: [
|
|
130
|
+
{ id: 'AC-1', title: 'Credentials management', required: true },
|
|
131
|
+
{ id: 'AC-2', title: 'Core integration', required: true },
|
|
132
|
+
{ id: 'AC-3', title: 'Error handling', required: true },
|
|
133
|
+
{ id: 'AC-4', title: 'Webhooks', required: false },
|
|
134
|
+
{ id: 'AC-5', title: 'Observability', required: false },
|
|
135
|
+
{ id: 'AC-6', title: 'Testing', required: true },
|
|
136
|
+
],
|
|
137
|
+
variables: [
|
|
138
|
+
{
|
|
139
|
+
key: 'ServiceName',
|
|
140
|
+
label: 'Service name',
|
|
141
|
+
description: 'Name of the external service to integrate',
|
|
142
|
+
example: 'Stripe',
|
|
143
|
+
required: true,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
key: 'IntegrationPurpose',
|
|
147
|
+
label: 'Purpose',
|
|
148
|
+
description: 'What the integration enables',
|
|
149
|
+
example: 'payment processing',
|
|
150
|
+
required: true,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
huTemplate: `# HU: {{ServiceName}} Integration
|
|
154
|
+
|
|
155
|
+
## User Story
|
|
156
|
+
As a developer, I want to integrate {{ServiceName}} so that the platform can handle {{IntegrationPurpose}} reliably.
|
|
157
|
+
|
|
158
|
+
## Acceptance Criteria
|
|
159
|
+
|
|
160
|
+
### AC-1: Credentials management
|
|
161
|
+
- [ ] API keys and secrets stored in environment variables (never hardcoded)
|
|
162
|
+
- [ ] Separate credentials for development, staging, and production
|
|
163
|
+
- [ ] Credential rotation documented in runbook
|
|
164
|
+
|
|
165
|
+
### AC-2: Core integration
|
|
166
|
+
- [ ] {{ServiceName}} SDK or HTTP client initialized with proper config
|
|
167
|
+
- [ ] All calls wrapped in retry logic with exponential backoff
|
|
168
|
+
- [ ] Timeouts configured (no infinite waits)
|
|
169
|
+
|
|
170
|
+
### AC-3: Error handling
|
|
171
|
+
- [ ] {{ServiceName}} API errors mapped to internal error types
|
|
172
|
+
- [ ] Network failures do not crash the application
|
|
173
|
+
- [ ] Errors logged with enough context for debugging
|
|
174
|
+
|
|
175
|
+
### AC-4: Webhooks (if applicable)
|
|
176
|
+
- [ ] Webhook endpoint validates signature before processing
|
|
177
|
+
- [ ] Events processed idempotently (replay-safe)
|
|
178
|
+
- [ ] Failed event processing alerts the on-call team
|
|
179
|
+
|
|
180
|
+
### AC-5: Observability
|
|
181
|
+
- [ ] All outbound calls logged (method, status, latency)
|
|
182
|
+
- [ ] Circuit breaker implemented for high-traffic paths
|
|
183
|
+
|
|
184
|
+
### AC-6: Testing
|
|
185
|
+
- [ ] Unit tests mock {{ServiceName}} client
|
|
186
|
+
- [ ] Integration tests use sandbox/test environment
|
|
187
|
+
- [ ] Webhook tests replay recorded payloads
|
|
188
|
+
`,
|
|
189
|
+
fichaTecnicaTemplate: `# FICHA TÉCNICA: {{ServiceName}} Integration
|
|
190
|
+
|
|
191
|
+
## Affected Files
|
|
192
|
+
- integrations/{{ServiceName}}/client
|
|
193
|
+
- integrations/{{ServiceName}}/webhook-handler
|
|
194
|
+
- integrations/{{ServiceName}}/error-mapper
|
|
195
|
+
- config/{{ServiceName}}-config
|
|
196
|
+
- tests/integrations/{{ServiceName}}
|
|
197
|
+
|
|
198
|
+
## Types / Entities
|
|
199
|
+
- \`{{ServiceName}}Config\`: apiKey, baseUrl, timeout, retries
|
|
200
|
+
- \`{{ServiceName}}Error\`: code, message, retryable
|
|
201
|
+
- \`WebhookEvent\`: id, type, payload, receivedAt
|
|
202
|
+
|
|
203
|
+
## Risks
|
|
204
|
+
- Vendor API changes without notice → pin SDK version, monitor changelogs
|
|
205
|
+
- Rate limits exceeded → implement request queuing
|
|
206
|
+
- Credentials leaked → secrets manager mandatory
|
|
207
|
+
|
|
208
|
+
## Estimation (rough)
|
|
209
|
+
- Dev: 8–20 hours
|
|
210
|
+
- Review: 2–4 hours
|
|
211
|
+
- Difficulty: 3/5
|
|
212
|
+
`,
|
|
213
|
+
progressTemplate: `# PROGRESS: {{ServiceName}} Integration
|
|
214
|
+
|
|
215
|
+
## Status: draft
|
|
216
|
+
|
|
217
|
+
## Criteria
|
|
218
|
+
- [ ] AC-1: Credentials management
|
|
219
|
+
- [ ] AC-2: Core integration
|
|
220
|
+
- [ ] AC-3: Error handling
|
|
221
|
+
- [ ] AC-4: Webhooks
|
|
222
|
+
- [ ] AC-5: Observability
|
|
223
|
+
- [ ] AC-6: Testing
|
|
224
|
+
`,
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=templates-perf-integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates-perf-integration.js","sourceRoot":"","sources":["../../../src/engine/spec-templates/templates-perf-integration.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,oEAAoE;AAIpE,8CAA8C;AAC9C,MAAM,CAAC,MAAM,iCAAiC,GAAsB;IAClE,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,aAAa;IACvB,WAAW,EAAE,mEAAmE;IAChF,IAAI,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,CAAC;IAC9D,eAAe,EAAE,GAAG;IACpB,cAAc,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,4DAA4D;KACpE;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC7D,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,IAAI,EAAE;QACpE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE;QACxD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;QACnD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE;KACxD;IACD,SAAS,EAAE;QACT;YACE,GAAG,EAAE,YAAY;YACjB,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,oEAAoE;YACjF,OAAO,EAAE,mBAAmB;YAC5B,QAAQ,EAAE,IAAI;SACf;QACD;YACE,GAAG,EAAE,iBAAiB;YACtB,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,qCAAqC;YAClD,OAAO,EAAE,oBAAoB;YAC7B,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,+BAA+B;SAC9C;QACD;YACE,GAAG,EAAE,YAAY;YACjB,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,+CAA+C;YAC5D,OAAO,EAAE,sBAAsB;YAC/B,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,yCAAyC;SACxD;KACF;IACD,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCb;IACC,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;CAoBvB;IACC,gBAAgB,EAAE;;;;;;;;;;CAUnB;CACA,CAAC;AAEF,6CAA6C;AAC7C,MAAM,CAAC,MAAM,gCAAgC,GAAsB;IACjE,EAAE,EAAE,yBAAyB;IAC7B,IAAI,EAAE,yBAAyB;IAC/B,QAAQ,EAAE,aAAa;IACvB,WAAW,EAAE,wEAAwE;IACrF,IAAI,EAAE,CAAC,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC;IACnD,eAAe,EAAE,GAAG;IACpB,cAAc,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,qDAAqD;KAC7D;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC/D,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE;QACvD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;QAClD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE;QACvD,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;KACjD;IACD,SAAS,EAAE;QACT;YACE,GAAG,EAAE,aAAa;YAClB,KAAK,EAAE,cAAc;YACrB,WAAW,EAAE,2CAA2C;YACxD,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,IAAI;SACf;QACD;YACE,GAAG,EAAE,oBAAoB;YACzB,KAAK,EAAE,SAAS;YAChB,WAAW,EAAE,8BAA8B;YAC3C,OAAO,EAAE,oBAAoB;YAC7B,QAAQ,EAAE,IAAI;SACf;KACF;IACD,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCb;IACC,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;CAuBvB;IACC,gBAAgB,EAAE;;;;;;;;;;;CAWnB;CACA,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HNSWConfig, HNSWSearchCandidate, HNSWSerializedState } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* HNSW (Hierarchical Navigable Small World) index.
|
|
4
|
+
* For corpus < flatSearchThreshold, delegates to brute-force flat search.
|
|
5
|
+
*/
|
|
6
|
+
export declare class HNSWIndex {
|
|
7
|
+
private readonly config;
|
|
8
|
+
private readonly nodes;
|
|
9
|
+
private entryPoint;
|
|
10
|
+
private maxLayer;
|
|
11
|
+
constructor(config?: Partial<HNSWConfig>);
|
|
12
|
+
/** Number of indexed vectors. */
|
|
13
|
+
get size(): number;
|
|
14
|
+
/** Insert a vector into the index. */
|
|
15
|
+
insert(id: string, vector: number[]): void;
|
|
16
|
+
/** Remove a vector from the index. */
|
|
17
|
+
remove(id: string): boolean;
|
|
18
|
+
/** Search for the top-K nearest neighbors. Uses flat search for small corpus. */
|
|
19
|
+
search(query: number[], topK: number): HNSWSearchCandidate[];
|
|
20
|
+
/** Brute-force flat search -- guaranteed recall = 1.0. */
|
|
21
|
+
private flatSearch;
|
|
22
|
+
/** HNSW graph search -- approximate, O(log n). */
|
|
23
|
+
private hnswSearch;
|
|
24
|
+
/** Greedy walk to the closest node in a given layer. */
|
|
25
|
+
private greedyClosest;
|
|
26
|
+
/** Search a single layer, returning ef closest candidates. */
|
|
27
|
+
private searchLayer;
|
|
28
|
+
/** Prune connections to keep at most M neighbors. */
|
|
29
|
+
private pruneConnections;
|
|
30
|
+
/** Random level for a new node (geometric distribution). */
|
|
31
|
+
private randomLevel;
|
|
32
|
+
/** Export the index for serialization. */
|
|
33
|
+
exportState(): HNSWSerializedState;
|
|
34
|
+
/** Import the index from serialized form. */
|
|
35
|
+
importState(state: HNSWSerializedState): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=hnsw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hnsw.d.ts","sourceRoot":"","sources":["../../../src/engine/vector-store/hnsw.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EAEV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAG9B;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAAK;gBAET,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC;IASxC,iCAAiC;IACjC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IA8D1C,sCAAsC;IACtC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IA2C3B,iFAAiF;IACjF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAa5D,0DAA0D;IAC1D,OAAO,CAAC,UAAU;IASlB,kDAAkD;IAClD,OAAO,CAAC,UAAU;IAelB,wDAAwD;IACxD,OAAO,CAAC,aAAa;IA6CrB,8DAA8D;IAC9D,OAAO,CAAC,WAAW;IAuEnB,qDAAqD;IACrD,OAAO,CAAC,gBAAgB;IAexB,4DAA4D;IAC5D,OAAO,CAAC,WAAW;IASnB,0CAA0C;IAC1C,WAAW,IAAI,mBAAmB;IASlC,6CAA6C;IAC7C,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;CAS9C"}
|