devendra-skill-package 1.0.2
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/.github/skills/boiler-project-generator/SKILL.md +103 -0
- package/.github/skills/boiler-project-generator/assets/templates/android/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/angular/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/flutter/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/ios/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/react/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/api-setup.ts +76 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/component-primary-button.tsx +29 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/env-config.env +4 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-auth-screen.tsx +45 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-dashboard-screen.tsx +45 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-profile-screen.tsx +45 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/hook-use-app-boot.ts +11 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/navigation-setup.tsx +25 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/project-structure.md +24 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-hooks.ts +5 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-session-slice.ts +29 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-store.ts +15 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/theme-index.ts +23 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/utils-helpers.ts +7 -0
- package/.github/skills/boiler-project-generator/metadata.yaml +29 -0
- package/.github/skills/boiler-project-generator/references/android.md +19 -0
- package/.github/skills/boiler-project-generator/references/angular.md +14 -0
- package/.github/skills/boiler-project-generator/references/flutter.md +17 -0
- package/.github/skills/boiler-project-generator/references/ios.md +17 -0
- package/.github/skills/boiler-project-generator/references/react-native.md +103 -0
- package/.github/skills/boiler-project-generator/references/react.md +17 -0
- package/.github/skills/boiler-project-generator/scripts/angular.js +43 -0
- package/.github/skills/boiler-project-generator/scripts/generate-project.mjs +107 -0
- package/.github/skills/boiler-project-generator/scripts/init.js +105 -0
- package/.github/skills/boiler-project-generator/scripts/react-native.js +1041 -0
- package/.github/skills/boiler-project-generator/scripts/react.js +32 -0
- package/.github/skills/clean-architecture-generator/SKILL.md +235 -0
- package/.github/skills/clean-architecture-generator/references/architecture-core.md +126 -0
- package/.github/skills/clean-architecture-generator/references/platform-angular.md +374 -0
- package/.github/skills/clean-architecture-generator/references/platform-flutter.md +366 -0
- package/.github/skills/clean-architecture-generator/references/platform-react-native.md +590 -0
- package/.github/skills/clean-architecture-generator/references/platform-react.md +261 -0
- package/.github/skills/code-test-coverage-analyzer/SKILL.md +1358 -0
- package/.github/skills/code-test-coverage-analyzer/assets/config-questionnaire.md +118 -0
- package/.github/skills/code-test-coverage-analyzer/assets/conflict-resolution-protocol.md +99 -0
- package/.github/skills/code-test-coverage-analyzer/assets/coverage-calculation-rules.md +294 -0
- package/.github/skills/code-test-coverage-analyzer/assets/multi-strategy-search.md +145 -0
- package/.github/skills/code-test-coverage-analyzer/assets/output-file-contracts.md +651 -0
- package/.github/skills/code-test-coverage-analyzer/assets/status-definitions.md +273 -0
- package/.github/skills/code-test-coverage-analyzer/examples/example-invocation.md +208 -0
- package/.github/skills/code-test-coverage-analyzer/references/android-patterns.md +229 -0
- package/.github/skills/code-test-coverage-analyzer/references/angular-patterns.md +177 -0
- package/.github/skills/code-test-coverage-analyzer/references/backend-patterns.md +383 -0
- package/.github/skills/code-test-coverage-analyzer/references/flutter-patterns.md +254 -0
- package/.github/skills/code-test-coverage-analyzer/references/ios-patterns.md +228 -0
- package/.github/skills/code-test-coverage-analyzer/references/react-native-patterns.md +431 -0
- package/.github/skills/code-test-coverage-analyzer/references/react-patterns.md +206 -0
- package/.github/skills/code-test-coverage-analyzer/scripts/detect-platform.ps1 +261 -0
- package/.github/skills/code-test-coverage-analyzer/scripts/scan-repository.ps1 +242 -0
- package/.github/skills/code-test-coverage-analyzer/templates/brd-compliance-row.md +107 -0
- package/.github/skills/code-test-coverage-analyzer/templates/test-case-row.md +130 -0
- package/.github/skills/code-test-coverage-analyzer/templates/user-story-compliance-row.md +170 -0
- package/.github/skills/custom-font-integrator/SKILL.md +373 -0
- package/.github/skills/custom-font-integrator/assets/FontTestScreen.js +150 -0
- package/.github/skills/custom-font-integrator/references/example-info-plist.xml +21 -0
- package/.github/skills/custom-font-integrator/scripts/setup-fonts.sh +99 -0
- package/.github/skills/encryption-decryption-utility/Instructions.md +282 -0
- package/.github/skills/encryption-decryption-utility/README.md +222 -0
- package/.github/skills/encryption-decryption-utility/SKILL.md +645 -0
- package/.github/skills/encryption-decryption-utility/assets/encryption-config-template.json +13 -0
- package/.github/skills/encryption-decryption-utility/assets/platform-matrix.json +180 -0
- package/.github/skills/encryption-decryption-utility/metadata.yaml +51 -0
- package/.github/skills/encryption-decryption-utility/references/android-crypto.md +157 -0
- package/.github/skills/encryption-decryption-utility/references/angular-crypto.md +130 -0
- package/.github/skills/encryption-decryption-utility/references/approach-1-webcrypto.md +95 -0
- package/.github/skills/encryption-decryption-utility/references/approach-2-rsa-aes-cbc.md +111 -0
- package/.github/skills/encryption-decryption-utility/references/approach-3-aes-sharedkey.md +114 -0
- package/.github/skills/encryption-decryption-utility/references/architecture.md +233 -0
- package/.github/skills/encryption-decryption-utility/references/backend-alignment.md +506 -0
- package/.github/skills/encryption-decryption-utility/references/dependency-guidance.md +234 -0
- package/.github/skills/encryption-decryption-utility/references/ec-implementation.md +832 -0
- package/.github/skills/encryption-decryption-utility/references/error-handling-playbook.md +234 -0
- package/.github/skills/encryption-decryption-utility/references/flutter-crypto.md +105 -0
- package/.github/skills/encryption-decryption-utility/references/ios-crypto.md +338 -0
- package/.github/skills/encryption-decryption-utility/references/native-rsa-implementation.md +373 -0
- package/.github/skills/encryption-decryption-utility/references/node-crypto.md +86 -0
- package/.github/skills/encryption-decryption-utility/references/react-crypto.md +105 -0
- package/.github/skills/encryption-decryption-utility/references/react-native-crypto.md +1001 -0
- package/.github/skills/encryption-decryption-utility/references/react-web-crypto.md +668 -0
- package/.github/skills/encryption-decryption-utility/references/security-checklist.md +176 -0
- package/.github/skills/encryption-decryption-utility/references/web-crypto.md +74 -0
- package/.github/skills/encryption-decryption-utility/scripts/detect.js +128 -0
- package/.github/skills/encryption-decryption-utility/scripts/install.js +1713 -0
- package/.github/skills/encryption-decryption-utility/scripts/setup.js +800 -0
- package/.github/skills/encryption-decryption-utility/template.md +241 -0
- package/.github/skills/encryption-decryption-utility/templates/config-questionnaire.md +467 -0
- package/.github/skills/encryption-decryption-utility/templates/delivery-checklist.md +206 -0
- package/.github/skills/encryption-decryption-utility/templates/implementation-plan.md +304 -0
- package/.github/skills/feature-generator/SKILL.MD +2741 -0
- package/.github/skills/feature-generator/assets/fingerprint-schema.json +385 -0
- package/.github/skills/feature-generator/assets/spec-template.md +172 -0
- package/.github/skills/feature-generator/assets/transform-rules.json +82 -0
- package/.github/skills/feature-generator/references/api-envelope-patterns.md +327 -0
- package/.github/skills/feature-generator/references/screen-logic-patterns.md +399 -0
- package/.github/skills/feature-generator/references/state-library-patterns.md +464 -0
- package/.github/skills/figma-ui-mapper/README.md +34 -0
- package/.github/skills/figma-ui-mapper/SKILL.md +101 -0
- package/.github/skills/figma-ui-mapper/assets/templates/component-map-template.md +30 -0
- package/.github/skills/figma-ui-mapper/assets/templates/generation-report-template.md +49 -0
- package/.github/skills/figma-ui-mapper/metadata.yaml +22 -0
- package/.github/skills/figma-ui-mapper/references/android.md +11 -0
- package/.github/skills/figma-ui-mapper/references/angular.md +18 -0
- package/.github/skills/figma-ui-mapper/references/capacitor.md +18 -0
- package/.github/skills/figma-ui-mapper/references/common.md +23 -0
- package/.github/skills/figma-ui-mapper/references/expo.md +18 -0
- package/.github/skills/figma-ui-mapper/references/flutter.md +18 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/angular/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/capacitor/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/expo/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/flutter/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/ionic/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/kotlin-multiplatform/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/native-android/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/native-ios/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/next/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/nuxt/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/react/rules.md +19 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/react-native/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/svelte/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/vue/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/ionic.md +18 -0
- package/.github/skills/figma-ui-mapper/references/ios.md +11 -0
- package/.github/skills/figma-ui-mapper/references/kotlin-multiplatform.md +18 -0
- package/.github/skills/figma-ui-mapper/references/native-android.md +18 -0
- package/.github/skills/figma-ui-mapper/references/native-ios.md +18 -0
- package/.github/skills/figma-ui-mapper/references/next.md +18 -0
- package/.github/skills/figma-ui-mapper/references/nuxt.md +18 -0
- package/.github/skills/figma-ui-mapper/references/react-figma-guideline.md +21 -0
- package/.github/skills/figma-ui-mapper/references/react-native.md +18 -0
- package/.github/skills/figma-ui-mapper/references/react.md +18 -0
- package/.github/skills/figma-ui-mapper/references/script-usage.md +46 -0
- package/.github/skills/figma-ui-mapper/references/svelte.md +18 -0
- package/.github/skills/figma-ui-mapper/references/vue.md +18 -0
- package/.github/skills/figma-ui-mapper/references/workflow.md +74 -0
- package/.github/skills/figma-ui-mapper/scripts/generate-page-through-figma.js +635 -0
- package/.github/skills/figma-ui-mapper/scripts/generate-react-page-through-figma.js +4 -0
- package/.github/skills/frontend-task-breakdown/SKILL.md +734 -0
- package/.github/skills/md-file-converter/SKILL.md +291 -0
- package/.github/skills/md-file-converter/config/formats.json +114 -0
- package/.github/skills/md-file-converter/extractors/extract-docx.sh +120 -0
- package/.github/skills/md-file-converter/extractors/extract-eml.py +108 -0
- package/.github/skills/md-file-converter/extractors/extract-pdf.sh +97 -0
- package/.github/skills/md-file-converter/extractors/extract-pptx.py +143 -0
- package/.github/skills/md-file-converter/extractors/extract-xlsx.py +175 -0
- package/.github/skills/md-file-converter/scripts/check-tools.sh +47 -0
- package/.github/skills/md-file-converter/scripts/extract-archive.sh +83 -0
- package/.github/skills/md-file-converter/scripts/extract-ocr.sh +77 -0
- package/.github/skills/md-file-converter/scripts/get-metadata.sh +57 -0
- package/.github/skills/md-file-converter/templates/output.md +73 -0
- package/.github/skills/md-file-converter/templates/unsupported-object.md +6 -0
- package/.github/skills/mockAPI-contract-generator/SKILL.md +607 -0
- package/.github/skills/test-case-validator/CHANGELOG.md +155 -0
- package/.github/skills/test-case-validator/CONFIGURATION.md +130 -0
- package/.github/skills/test-case-validator/EXAMPLES.md +50 -0
- package/.github/skills/test-case-validator/QUALITY_SCORING.md +98 -0
- package/.github/skills/test-case-validator/README.md +111 -0
- package/.github/skills/test-case-validator/REPORT_TEMPLATE.md +116 -0
- package/.github/skills/test-case-validator/SKILL.md +209 -0
- package/.github/skills/test-case-validator/SYSTEM_PROMPT.md +127 -0
- package/.github/skills/test-case-validator/TRACEABILITY_ENGINE.md +152 -0
- package/.github/skills/test-case-validator/VALIDATION_RULES.md +411 -0
- package/.github/skills/test-case-validator/config/default.config.yaml +62 -0
- package/.github/skills/test-case-validator/docs/ARCHITECTURE.md +66 -0
- package/.github/skills/test-case-validator/docs/EXTENDING.md +85 -0
- package/.github/skills/test-case-validator/docs/FAQ.md +88 -0
- package/.github/skills/test-case-validator/docs/VERSIONING.md +55 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-brd.md +43 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-test-cases.csv +9 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-user-story.md +29 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/output-report.md +303 -0
- package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/input-spec.md +43 -0
- package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/input-test-files-index.md +56 -0
- package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/output-report.md +274 -0
- package/.github/skills/test-case-validator/prompts/00-applicability-resolution.md +61 -0
- package/.github/skills/test-case-validator/prompts/01-extraction-user-story.md +58 -0
- package/.github/skills/test-case-validator/prompts/02-extraction-brd.md +64 -0
- package/.github/skills/test-case-validator/prompts/03-extraction-test-cases.md +92 -0
- package/.github/skills/test-case-validator/prompts/04-traceability-matrix.md +41 -0
- package/.github/skills/test-case-validator/prompts/05-coverage-analysis.md +46 -0
- package/.github/skills/test-case-validator/prompts/06-missing-scenario-detection.md +32 -0
- package/.github/skills/test-case-validator/prompts/07-duplicate-detection.md +36 -0
- package/.github/skills/test-case-validator/prompts/08-risk-analysis.md +39 -0
- package/.github/skills/test-case-validator/prompts/09-gated-wiring-validation.md +53 -0
- package/.github/skills/test-case-validator/prompts/10-observation-report.md +56 -0
- package/.github/skills/test-case-validator/prompts/11-final-report-assembly.md +57 -0
- package/.github/skills/test-case-validator/templates/coverage-table.md +25 -0
- package/.github/skills/test-case-validator/templates/executive-summary.md +38 -0
- package/.github/skills/test-case-validator/templates/final-summary-block.md +87 -0
- package/.github/skills/test-case-validator/templates/observation-entry.md +41 -0
- package/.github/skills/test-case-validator/templates/rtm-row.md +25 -0
- package/.github/skills/validation-engine-builder/README.md +50 -0
- package/.github/skills/validation-engine-builder/SKILL.md +241 -0
- package/.github/skills/validation-engine-builder/references/core.md +158 -0
- package/.github/skills/validation-engine-builder/references/platform-angular.md +166 -0
- package/.github/skills/validation-engine-builder/references/platform-flutter.md +118 -0
- package/.github/skills/validation-engine-builder/references/platform-react-native.md +170 -0
- package/.github/skills/validation-engine-builder/references/platform-react.md +94 -0
- package/.github/skills/validation-engine-builder/scripts/apply-to-project.js +80 -0
- package/.github/skills/validation-engine-builder/scripts/generate-angular.js +271 -0
- package/.github/skills/validation-engine-builder/scripts/generate-flutter.js +298 -0
- package/.github/skills/validation-engine-builder/scripts/generate-react-native.js +217 -0
- package/.github/skills/validation-engine-builder/scripts/generate-react.js +163 -0
- package/.github/skills/validation-engine-builder/scripts/install-deps.js +53 -0
- package/.github/skills/validation-engine-builder/scripts/shared/detect-platform.js +68 -0
- package/.github/skills/validation-engine-builder/scripts/shared/npm-deps.js +103 -0
- package/.github/skills/validation-engine-builder/scripts/shared/rhf-hook.js +43 -0
- package/.github/skills/validation-engine-builder/scripts/shared/ts-messages-regex.js +62 -0
- package/.github/skills/validation-engine-builder/scripts/shared/util.js +44 -0
- package/.github/skills/validation-engine-builder/scripts/shared/yup-schemas.js +80 -0
- package/.github/skills/validation-engine-builder/template.md +73 -0
- package/.github/skills/validation-engine-builder/templates/messages.json +22 -0
- package/.github/skills/validation-engine-builder/templates/regex.json +16 -0
- package/.github/skills/validation-engine-builder/templates/schemas.json +48 -0
- package/bin/index.js +145 -0
- package/package.json +22 -0
- package/readme.md +0 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "feature-generator/fingerprint",
|
|
4
|
+
"title": "Architecture Fingerprint",
|
|
5
|
+
"description": "Produced by Phase 0 of feature-generator. Every field marked required must be resolved before Phases 1-7 run. Fields marked [INFERRED] must be visually flagged in output.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"repoRoot",
|
|
9
|
+
"appRoot",
|
|
10
|
+
"appRootRelative",
|
|
11
|
+
"featureStyle",
|
|
12
|
+
"featuresRoot",
|
|
13
|
+
"layerMap",
|
|
14
|
+
"maxLayerDepth",
|
|
15
|
+
"importPrefixToAppRoot",
|
|
16
|
+
"sharedRoot",
|
|
17
|
+
"apiLib",
|
|
18
|
+
"apiClientFile",
|
|
19
|
+
"apiClientImport",
|
|
20
|
+
"envelopeStyle",
|
|
21
|
+
"mockSystem",
|
|
22
|
+
"stateLib",
|
|
23
|
+
"thunkPattern",
|
|
24
|
+
"storeConfigFile",
|
|
25
|
+
"rootStateTypeFile",
|
|
26
|
+
"rootStateImport",
|
|
27
|
+
"navLib",
|
|
28
|
+
"tsStrict",
|
|
29
|
+
"quoteStyle",
|
|
30
|
+
"semi",
|
|
31
|
+
"tabWidth",
|
|
32
|
+
"fileNameStyle",
|
|
33
|
+
"classStyle",
|
|
34
|
+
"interfacePrefix",
|
|
35
|
+
"featureFolderStyle",
|
|
36
|
+
"diStyle",
|
|
37
|
+
"returnTypeStyle"
|
|
38
|
+
],
|
|
39
|
+
"properties": {
|
|
40
|
+
"repoRoot": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Absolute path to the repository root (directory containing package.json with react-native dependency)."
|
|
43
|
+
},
|
|
44
|
+
"appRoot": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "Absolute path to the React Native app source root (where App.tsx / index.js lives)."
|
|
47
|
+
},
|
|
48
|
+
"appRootRelative": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"description": "Path of appRoot relative to repoRoot. Example: 'src/' or '' if equal.",
|
|
51
|
+
"examples": ["src/", "app/", ""]
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
"featureStyle": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"enum": ["feature-first", "layer-first", "expo-router", "domain-driven", "atomic", "monorepo"],
|
|
57
|
+
"description": "Dominant organisation style detected in Phase 0.B."
|
|
58
|
+
},
|
|
59
|
+
"featureStyleSecondary": {
|
|
60
|
+
"type": ["string", "null"],
|
|
61
|
+
"description": "Secondary style if mixed. Null if clean single-style."
|
|
62
|
+
},
|
|
63
|
+
"featuresRoot": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"description": "Path relative to appRoot where feature directories live. Example: 'features/', 'modules/', 'pages/'."
|
|
66
|
+
},
|
|
67
|
+
"featureDirSample": {
|
|
68
|
+
"type": "array",
|
|
69
|
+
"items": { "type": "string" },
|
|
70
|
+
"minItems": 1,
|
|
71
|
+
"description": "3-5 example feature directory names found under featuresRoot."
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"layerMap": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"description": "Actual folder name segments for each architectural layer, detected from the sample feature directory. Null means the layer does not exist in this project — skip generation for that layer.",
|
|
77
|
+
"required": ["domain", "data", "state", "presentation"],
|
|
78
|
+
"properties": {
|
|
79
|
+
"domain": { "type": ["string", "null"] },
|
|
80
|
+
"domainModels": { "type": ["string", "null"], "description": "Relative path from feature root to domain models. Example: 'domain/models'" },
|
|
81
|
+
"domainRepo": { "type": ["string", "null"], "description": "Relative path from feature root to domain repository interfaces." },
|
|
82
|
+
"useCases": { "type": ["string", "null"], "description": "Relative path from feature root to use case files." },
|
|
83
|
+
"data": { "type": ["string", "null"] },
|
|
84
|
+
"dataSource": { "type": ["string", "null"], "description": "Relative path from feature root to API datasource files." },
|
|
85
|
+
"repoImpl": { "type": ["string", "null"], "description": "Relative path from feature root to repository implementation files. Example: 'data/repositories'" },
|
|
86
|
+
"dtos": { "type": ["string", "null"], "description": "Relative path from feature root to DTO files. Null = inline DTOs in mapper." },
|
|
87
|
+
"mappers": { "type": ["string", "null"] },
|
|
88
|
+
"mocks": { "type": ["string", "null"], "description": "Relative path from feature root to mock JSON files." },
|
|
89
|
+
"state": { "type": ["string", "null"] },
|
|
90
|
+
"stateStore": { "type": ["string", "null"], "description": "Relative path from feature root to slice/store files." },
|
|
91
|
+
"selectors": { "type": ["string", "null"], "description": "Relative path from feature root to selector files. Null = inline selectors in slice." },
|
|
92
|
+
"presentation": { "type": ["string", "null"] },
|
|
93
|
+
"screens": { "type": ["string", "null"], "description": "Relative path from feature root to screen components." },
|
|
94
|
+
"di": { "type": ["string", "null"], "description": "Relative path from feature root to DI container directory. Example: 'di'. Null if diStyle is not per-feature-container." }
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
"maxLayerDepth": {
|
|
99
|
+
"type": "integer",
|
|
100
|
+
"minimum": 1,
|
|
101
|
+
"description": "Number of directory segments from appRoot to the deepest layer file. Used to compute import prefixes."
|
|
102
|
+
},
|
|
103
|
+
"importPrefixToAppRoot": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"pattern": "^(\\.\\./)+$",
|
|
106
|
+
"description": "Relative prefix to climb back to appRoot from the deepest layer. Example: '../../../../'."
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
"sharedRoot": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"description": "Path relative to appRoot for the shared/common utilities directory. Example: 'shared/', 'common/', 'core/'."
|
|
112
|
+
},
|
|
113
|
+
"sharedRootAlias": {
|
|
114
|
+
"type": ["string", "null"],
|
|
115
|
+
"description": "Import alias for sharedRoot if one exists. Example: '@shared'. Null if no alias."
|
|
116
|
+
},
|
|
117
|
+
"sharedApiDir": {
|
|
118
|
+
"type": ["string", "null"],
|
|
119
|
+
"description": "Path relative to appRoot for the shared API client file's directory."
|
|
120
|
+
},
|
|
121
|
+
"sharedTypesDir": {
|
|
122
|
+
"type": ["string", "null"],
|
|
123
|
+
"description": "Path relative to appRoot for shared TypeScript types."
|
|
124
|
+
},
|
|
125
|
+
"sharedStoreDir": {
|
|
126
|
+
"type": ["string", "null"],
|
|
127
|
+
"description": "Path relative to appRoot for the Redux store config (or equivalent)."
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
"aliasesDetected": {
|
|
131
|
+
"type": "boolean",
|
|
132
|
+
"description": "True if tsconfig/babel/metro defines path aliases."
|
|
133
|
+
},
|
|
134
|
+
"aliasMap": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"description": "Map of alias prefix to resolved path relative to repoRoot. Example: { '@': 'src/', '@shared': 'src/shared/' }.",
|
|
137
|
+
"additionalProperties": { "type": "string" }
|
|
138
|
+
},
|
|
139
|
+
"preferAliases": {
|
|
140
|
+
"type": "boolean",
|
|
141
|
+
"description": "True if existing feature files actually use aliases in their imports. If false, use relative paths even when aliases are defined."
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
"apiLib": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"enum": ["axios", "fetch", "rtk-query", "react-query", "apollo", "other"],
|
|
147
|
+
"description": "HTTP client library detected across the codebase."
|
|
148
|
+
},
|
|
149
|
+
"apiClientFile": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"description": "Absolute path to the shared API client instance file."
|
|
152
|
+
},
|
|
153
|
+
"apiClientImport": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"description": "Exact import string used by existing feature datasource files to import the client. Example: '../../../../shared/api/apiClient'."
|
|
156
|
+
},
|
|
157
|
+
"envelopeStyle": {
|
|
158
|
+
"type": "string",
|
|
159
|
+
"enum": ["mb-operationId", "mb-operationid-lowercase", "none", "graphql", "other"],
|
|
160
|
+
"description": "Request body envelope pattern detected from existing API calls. See references/api-envelope-patterns.md."
|
|
161
|
+
},
|
|
162
|
+
"envelopeBuilder": {
|
|
163
|
+
"type": ["string", "null"],
|
|
164
|
+
"description": "Name of the buildEnvelope helper function and its source file if one exists. 'inline' if envelope is constructed inline. Null if no envelope."
|
|
165
|
+
},
|
|
166
|
+
"mockSystem": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"enum": ["mockConfig", "msw", "none"],
|
|
169
|
+
"description": "Mock data strategy detected in the project."
|
|
170
|
+
},
|
|
171
|
+
"mockConfigFile": {
|
|
172
|
+
"type": ["string", "null"],
|
|
173
|
+
"description": "Absolute path to mockConfig.ts (or equivalent). Null if mockSystem is 'none'."
|
|
174
|
+
},
|
|
175
|
+
"mockGlobalFlag": {
|
|
176
|
+
"type": ["string", "null"],
|
|
177
|
+
"description": "Exact field name for the global mock toggle in mockConfig. Example: 'globalMockEnabled'."
|
|
178
|
+
},
|
|
179
|
+
"mockDelayField": {
|
|
180
|
+
"type": ["string", "null"],
|
|
181
|
+
"description": "Exact field name for the simulated delay value in mockConfig. Example: 'simulatedDelayMs'."
|
|
182
|
+
},
|
|
183
|
+
"mockJsonFolder": {
|
|
184
|
+
"type": ["string", "null"],
|
|
185
|
+
"description": "Path pattern for mock JSON files, relative to the datasource file. Example: './__mocks__/'."
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
"stateLib": {
|
|
189
|
+
"type": "string",
|
|
190
|
+
"enum": ["redux-toolkit", "zustand", "mobx", "context-api", "react-query", "jotai", "recoil", "other"],
|
|
191
|
+
"description": "Dominant state management library detected."
|
|
192
|
+
},
|
|
193
|
+
"thunkPattern": {
|
|
194
|
+
"type": "string",
|
|
195
|
+
"enum": ["thunk-extra", "direct-import", "rtk-query", "n/a"],
|
|
196
|
+
"description": "How Redux async thunks receive their dependencies. 'n/a' for non-RTK state libs."
|
|
197
|
+
},
|
|
198
|
+
"storeConfigFile": {
|
|
199
|
+
"type": ["string", "null"],
|
|
200
|
+
"description": "Absolute path to the file containing configureStore() call."
|
|
201
|
+
},
|
|
202
|
+
"rootStateTypeFile": {
|
|
203
|
+
"type": ["string", "null"],
|
|
204
|
+
"description": "Absolute path to the file that exports the RootState type."
|
|
205
|
+
},
|
|
206
|
+
"rootStateImport": {
|
|
207
|
+
"type": ["string", "null"],
|
|
208
|
+
"description": "Exact import string to reach RootState from a selector file at maxLayerDepth. Example: '../../../../app/store'."
|
|
209
|
+
},
|
|
210
|
+
"sliceNameStyle": {
|
|
211
|
+
"type": "string",
|
|
212
|
+
"enum": ["camelCase", "kebab-case"],
|
|
213
|
+
"description": "Naming style used for the Redux slice 'name' string. Derived from existing slices."
|
|
214
|
+
},
|
|
215
|
+
"reducerMapKeys": {
|
|
216
|
+
"type": "array",
|
|
217
|
+
"items": { "type": "string" },
|
|
218
|
+
"description": "Existing reducer keys in the store's reducer map. New feature key must not collide."
|
|
219
|
+
},
|
|
220
|
+
"reducerKey": {
|
|
221
|
+
"type": ["string", "null"],
|
|
222
|
+
"description": "Single-mode only: the reducer key derived in Phase 1.4 for the one screen being generated. In module mode this is null — each screen's reducerKey is computed per-screen in Phase 1.4 and is NOT stored in the fingerprint."
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
"navLib": {
|
|
226
|
+
"type": "string",
|
|
227
|
+
"enum": ["react-navigation", "expo-router", "wix-navigation", "none"],
|
|
228
|
+
"description": "Navigation library detected."
|
|
229
|
+
},
|
|
230
|
+
"navVersion": {
|
|
231
|
+
"type": ["string", "null"],
|
|
232
|
+
"enum": ["5", "6", "7", "n/a", null],
|
|
233
|
+
"description": "React Navigation major version. 'n/a' or null for other libs."
|
|
234
|
+
},
|
|
235
|
+
"navStackType": {
|
|
236
|
+
"type": ["string", "null"],
|
|
237
|
+
"enum": ["native-stack", "stack", "bottom-tab", "n/a", null],
|
|
238
|
+
"description": "Stack type used by the existing navigator that the new screen will be added to."
|
|
239
|
+
},
|
|
240
|
+
"navScreenFile": {
|
|
241
|
+
"type": ["string", "null"],
|
|
242
|
+
"description": "Absolute path to the navigator file where screens are registered."
|
|
243
|
+
},
|
|
244
|
+
"navParamsPattern": {
|
|
245
|
+
"type": ["string", "null"],
|
|
246
|
+
"description": "Name of the params list type used for screen params. Example: 'PortfolioStackParamList'."
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
"tsStrict": {
|
|
250
|
+
"type": "boolean",
|
|
251
|
+
"description": "Whether tsconfig compilerOptions.strict is true. When true, all entity fields must be readonly."
|
|
252
|
+
},
|
|
253
|
+
"noImplicitAny": {
|
|
254
|
+
"type": "boolean",
|
|
255
|
+
"description": "Whether tsconfig compilerOptions.noImplicitAny is true."
|
|
256
|
+
},
|
|
257
|
+
"strictNullChecks": {
|
|
258
|
+
"type": "boolean",
|
|
259
|
+
"description": "Whether tsconfig compilerOptions.strictNullChecks is true."
|
|
260
|
+
},
|
|
261
|
+
"explicitReturnType": {
|
|
262
|
+
"type": "boolean",
|
|
263
|
+
"description": "Whether ESLint enforces explicit function return types. When true, add return types to all functions."
|
|
264
|
+
},
|
|
265
|
+
"quoteStyle": {
|
|
266
|
+
"type": "string",
|
|
267
|
+
"enum": ["single", "double"],
|
|
268
|
+
"description": "Quote style from Prettier config."
|
|
269
|
+
},
|
|
270
|
+
"trailingComma": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"enum": ["es5", "all", "none"],
|
|
273
|
+
"description": "Trailing comma style from Prettier config."
|
|
274
|
+
},
|
|
275
|
+
"semi": {
|
|
276
|
+
"type": "boolean",
|
|
277
|
+
"description": "Whether Prettier adds semicolons."
|
|
278
|
+
},
|
|
279
|
+
"tabWidth": {
|
|
280
|
+
"type": "integer",
|
|
281
|
+
"enum": [2, 4],
|
|
282
|
+
"description": "Indentation width from Prettier config."
|
|
283
|
+
},
|
|
284
|
+
"testRunner": {
|
|
285
|
+
"type": ["string", "null"],
|
|
286
|
+
"enum": ["jest", "vitest", "mocha", "none", null]
|
|
287
|
+
},
|
|
288
|
+
"testFilePattern": {
|
|
289
|
+
"type": ["string", "null"],
|
|
290
|
+
"description": "Test file naming pattern. Example: '*.test.ts', '*.spec.ts', '__tests__/'."
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
"fileNameStyle": {
|
|
294
|
+
"type": "string",
|
|
295
|
+
"enum": ["camelCase", "kebab-case", "PascalCase"],
|
|
296
|
+
"description": "Naming style for TypeScript source files (excluding screen components which are always PascalCase)."
|
|
297
|
+
},
|
|
298
|
+
"classStyle": {
|
|
299
|
+
"type": "string",
|
|
300
|
+
"enum": ["PascalCase"],
|
|
301
|
+
"description": "Always PascalCase for class names."
|
|
302
|
+
},
|
|
303
|
+
"interfacePrefix": {
|
|
304
|
+
"type": "string",
|
|
305
|
+
"enum": ["I", "none"],
|
|
306
|
+
"description": "Whether repository interfaces are prefixed with 'I'. Detected from existing domain files."
|
|
307
|
+
},
|
|
308
|
+
"operationIdStyle": {
|
|
309
|
+
"type": "string",
|
|
310
|
+
"enum": ["PascalCase-Get", "path-style", "camelCase"],
|
|
311
|
+
"description": "Casing style for operationId strings in envelope calls."
|
|
312
|
+
},
|
|
313
|
+
"mockJsonStyle": {
|
|
314
|
+
"type": "string",
|
|
315
|
+
"description": "File name pattern for mock JSON files. Example: 'camelCase.mock.json', 'PascalCase.mock.json'."
|
|
316
|
+
},
|
|
317
|
+
"featureFolderStyle": {
|
|
318
|
+
"type": "string",
|
|
319
|
+
"enum": ["camelCase", "kebab-case", "PascalCase"],
|
|
320
|
+
"description": "Naming style for feature directory names."
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
"diStyle": {
|
|
324
|
+
"type": "string",
|
|
325
|
+
"enum": ["per-feature-bootstrap", "per-feature-container", "global", "none"],
|
|
326
|
+
"description": "DI wiring pattern detected across feature directories. See Phase 6 in SKILL.MD for generation templates per style."
|
|
327
|
+
},
|
|
328
|
+
"diBootstrapFile": {
|
|
329
|
+
"type": ["string", "null"],
|
|
330
|
+
"description": "Path relative to feature root for the per-feature-bootstrap file (e.g. 'diBootstrap.ts'). Null when diStyle is not per-feature-bootstrap."
|
|
331
|
+
},
|
|
332
|
+
"diContainerFile": {
|
|
333
|
+
"type": ["string", "null"],
|
|
334
|
+
"description": "Path relative to feature root for the per-feature-container file (e.g. 'di/container.ts'). Null when diStyle is not per-feature-container."
|
|
335
|
+
},
|
|
336
|
+
"diContainerClass": {
|
|
337
|
+
"type": ["string", "null"],
|
|
338
|
+
"description": "Class name used in the existing DI container (e.g. 'ReportsContainer'). Null when diStyle is not per-feature-container."
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
"returnTypeStyle": {
|
|
342
|
+
"type": "string",
|
|
343
|
+
"enum": ["result-wrapper", "custom-type", "direct-promise"],
|
|
344
|
+
"description": "How domain repository methods return values. Controls Phase 3.2, 4.7, and 5.1 code generation. result-wrapper = Promise<{ ok, data?, error? }>; custom-type = Promise<NamedType>; direct-promise = Promise<T[]> throws on error."
|
|
345
|
+
},
|
|
346
|
+
"resultTypeImport": {
|
|
347
|
+
"type": ["string", "null"],
|
|
348
|
+
"description": "Exact import string for the shared Result<T> type when returnTypeStyle is 'result-wrapper'. Null otherwise."
|
|
349
|
+
},
|
|
350
|
+
"repoReturnWrapper": {
|
|
351
|
+
"type": ["string", "null"],
|
|
352
|
+
"description": "Name of the custom return type when returnTypeStyle is 'custom-type' (e.g. 'PortfolioSummaryResult'). Null otherwise."
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
"layerMapVariants": {
|
|
356
|
+
"type": "object",
|
|
357
|
+
"description": "Records all alternative folder name variants found across feature directories for layers that differ. Key = layerMap property name; value = array of all observed path strings.",
|
|
358
|
+
"additionalProperties": {
|
|
359
|
+
"type": "array",
|
|
360
|
+
"items": { "type": "string" },
|
|
361
|
+
"minItems": 1
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
"screenRefPatterns": {
|
|
366
|
+
"type": "array",
|
|
367
|
+
"description": "Populated in Phase 0.L when SCREEN_REF_PATHS are provided. Each entry describes the UI conventions extracted from one reference screen file.",
|
|
368
|
+
"items": {
|
|
369
|
+
"type": "object",
|
|
370
|
+
"required": ["file"],
|
|
371
|
+
"properties": {
|
|
372
|
+
"file": { "type": "string", "description": "Relative path to the reference screen file." },
|
|
373
|
+
"scrollContainer": { "type": "string", "enum": ["FlatList", "ScrollView", "FlashList", "other"] },
|
|
374
|
+
"styleNames": { "type": "array", "items": { "type": "string" } },
|
|
375
|
+
"sharedComponents":{ "type": "array", "items": { "type": "string" } },
|
|
376
|
+
"navHook": { "type": "string", "enum": ["useNavigation", "useRouter", "none"] },
|
|
377
|
+
"stateHooks": { "type": "array", "items": { "type": "string" } },
|
|
378
|
+
"earlyReturnOrder":{ "type": "array", "items": { "type": "string" } },
|
|
379
|
+
"listItemLayout": { "type": "string" }
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
"additionalProperties": false
|
|
385
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Feature Spec: <ScreenName>
|
|
2
|
+
|
|
3
|
+
<!-- INSTRUCTIONS
|
|
4
|
+
- Replace <ScreenName> in the heading above with a PascalCase name (e.g. TransactionHistory).
|
|
5
|
+
- Fill in every section below. Sections marked REQUIRED will cause a FATAL if missing.
|
|
6
|
+
- Sections marked OPTIONAL will produce a WARN if missing but generation will continue.
|
|
7
|
+
- Sections marked INTERVIEW map to the 5 mandatory questions in PHASE -1.
|
|
8
|
+
If you fill them here, they are treated as your answers to those questions.
|
|
9
|
+
- Delete all HTML comments before using this file as input.
|
|
10
|
+
|
|
11
|
+
USAGE MODES:
|
|
12
|
+
─────────────────────────────────────────────────────────────────
|
|
13
|
+
Single screen:
|
|
14
|
+
Fill ONE copy of this template. Provide it as the spec for one screen.
|
|
15
|
+
|
|
16
|
+
Module (multiple screens):
|
|
17
|
+
Create ONE copy of this template per screen. Name them clearly, e.g.:
|
|
18
|
+
fdBooking-fdDetails-spec.md
|
|
19
|
+
fdBooking-payment-spec.md
|
|
20
|
+
fdBooking-confirmation-spec.md
|
|
21
|
+
During the PHASE -1 interview, provide all file paths when asked for design sources.
|
|
22
|
+
The skill generates all screens under one shared module folder and creates a single
|
|
23
|
+
diBootstrap.ts for the whole module.
|
|
24
|
+
─────────────────────────────────────────────────────────────────
|
|
25
|
+
-->
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Screen Name
|
|
30
|
+
<!-- INTERVIEW Q1 — REQUIRED. PascalCase. Used to derive all file names, class names, and operation IDs.
|
|
31
|
+
If you filled the Screen Name in the PHASE -1 Q1 interview, it overrides this field.
|
|
32
|
+
Examples: TransactionHistory FundDetail UserProfile ReportDownload -->
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## User Stories
|
|
38
|
+
<!-- INTERVIEW Q2 — OPTIONAL. One story per bullet.
|
|
39
|
+
Format: As a <role>, I want to <action> so that <benefit>.
|
|
40
|
+
These drive screen logic completeness and post-generation user story coverage checks.
|
|
41
|
+
If not provided, screen logic will be derived from the Screen Logic section below.
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
- As a user, I want to see my transaction history so that I can track my investments
|
|
45
|
+
- As a user, I want to pull to refresh so that I get the latest data
|
|
46
|
+
- As a user, I want to tap a transaction to see its full details
|
|
47
|
+
-->
|
|
48
|
+
-
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Test Cases
|
|
53
|
+
<!-- INTERVIEW Q3 — OPTIONAL. One case per bullet.
|
|
54
|
+
Format: Given <state>, when <action>, then <expected outcome>.
|
|
55
|
+
Label type at the end: [happy] [edge] [error]
|
|
56
|
+
These drive post-generation test case coverage checks.
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
- Given data is available, when screen loads, then list renders all transactions [happy]
|
|
60
|
+
- Given list is empty, when screen loads, then empty state message is shown [edge]
|
|
61
|
+
- Given API returns Status != "success", when screen loads, then error message is shown [error]
|
|
62
|
+
- Given user is unauthenticated, when screen loads, then logout prompt is shown [error]
|
|
63
|
+
-->
|
|
64
|
+
-
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## API URL
|
|
69
|
+
<!-- REQUIRED. Endpoint path as it appears in the API contract.
|
|
70
|
+
Include the full path from the service root (no base URL).
|
|
71
|
+
Examples:
|
|
72
|
+
/api/v1/portfolio/transactions
|
|
73
|
+
/api/v1/boreports/fund-exposure
|
|
74
|
+
/GetPortfolioSummary -->
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## HTTP Method
|
|
80
|
+
<!-- REQUIRED. One of: GET POST PUT PATCH DELETE -->
|
|
81
|
+
POST
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Request Body
|
|
86
|
+
<!-- OPTIONAL (default: {}). JSON object sent to the server.
|
|
87
|
+
Use EXACT field names and casing as expected by the API.
|
|
88
|
+
The skill will map camelCase params to these names in the datasource.
|
|
89
|
+
For GET requests write: {} -->
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Response Shape
|
|
98
|
+
<!-- OPTIONAL. Example JSON response from the API.
|
|
99
|
+
Include all fields that appear in Response Mapping below.
|
|
100
|
+
Use realistic placeholder values, not nulls.
|
|
101
|
+
If the response is an array at the root, wrap it in an object:
|
|
102
|
+
{ "Data": [ { ... } ] }
|
|
103
|
+
-->
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"Status": "success",
|
|
107
|
+
"Data": []
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Business Logic
|
|
114
|
+
<!-- OPTIONAL. One rule per bullet. Pure domain logic only.
|
|
115
|
+
Domain rules = validation, derived values, thresholds, status interpretation.
|
|
116
|
+
These become guard clauses in the UseCase.execute() method.
|
|
117
|
+
Do NOT include UI behaviour here (goes in Screen Logic).
|
|
118
|
+
|
|
119
|
+
Examples:
|
|
120
|
+
- Only show items where Amount > 0
|
|
121
|
+
- If Status is not "success", treat the response as an error
|
|
122
|
+
- Items older than 7 years should be marked as "Archived"
|
|
123
|
+
- XIRR below -100 should be clamped to -100
|
|
124
|
+
-->
|
|
125
|
+
-
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Screen Logic
|
|
130
|
+
<!-- INTERVIEW Q5E — OPTIONAL. One rule per bullet. UI behaviour only.
|
|
131
|
+
Maps to PHASE -1 Question 5E. If filled here, treated as your Q5E answer.
|
|
132
|
+
Screen logic = what happens on mount, user gestures, navigation, state changes.
|
|
133
|
+
These become useEffect / callback / conditional render in the Screen component.
|
|
134
|
+
Do NOT include domain validation here (goes in Business Logic).
|
|
135
|
+
|
|
136
|
+
Examples:
|
|
137
|
+
- Fetch data on screen mount
|
|
138
|
+
- Support pull-to-refresh
|
|
139
|
+
- Navigate to DetailScreen when user taps a row
|
|
140
|
+
- Show empty state message "No items found" when list is empty
|
|
141
|
+
- Filter by category using a tab bar
|
|
142
|
+
- Show loading skeleton while data is fetching
|
|
143
|
+
- Display auth error message and logout button if session expires
|
|
144
|
+
-->
|
|
145
|
+
-
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Response Mapping
|
|
150
|
+
<!-- OPTIONAL but strongly recommended. One line per field.
|
|
151
|
+
Format: `response.field.path` → description of where and how it appears in the UI
|
|
152
|
+
|
|
153
|
+
Apply transform keywords inline after the description:
|
|
154
|
+
formatted as Indian currency → ₹1,23,456.78
|
|
155
|
+
formatted as date DD MMM YYYY → 15 Jan 2024
|
|
156
|
+
formatted as percentage → 12.34%
|
|
157
|
+
formatted as boolean badge → green/red coloured label
|
|
158
|
+
|
|
159
|
+
Other transforms (see assets/transform-rules.json for full list):
|
|
160
|
+
formatted as compact number → 1.2 Cr, 45 L
|
|
161
|
+
formatted as units → 12.345 units
|
|
162
|
+
|
|
163
|
+
Examples:
|
|
164
|
+
- `Data[].TransactionID` → unique key for each row (not visible)
|
|
165
|
+
- `Data[].FundName` → primary title of each list row
|
|
166
|
+
- `Data[].Amount` → below title, formatted as Indian currency
|
|
167
|
+
- `Data[].TransactionDate` → subtitle, formatted as date DD MMM YYYY
|
|
168
|
+
- `Data[].TransactionType` → badge: green for "Purchase", red for "Redemption", formatted as boolean badge
|
|
169
|
+
- `Data[].Units` → detail row: "Units: <value>"
|
|
170
|
+
- `Data[].NAV` → detail row, formatted as Indian currency
|
|
171
|
+
-->
|
|
172
|
+
-
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Response mapping transform rules. Keys are lowercase keywords matched against the transform string in spec responseMappings. {value} is replaced with the actual TypeScript expression at code-generation time.",
|
|
3
|
+
|
|
4
|
+
"transforms": {
|
|
5
|
+
"formatted as indian currency": {
|
|
6
|
+
"tsExpression": "{value}.toLocaleString('en-IN', { style: 'currency', currency: 'INR', minimumFractionDigits: 2, maximumFractionDigits: 2 })",
|
|
7
|
+
"nullSafe": "typeof {value} === 'number' ? {value}.toLocaleString('en-IN', { style: 'currency', currency: 'INR', minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '--'",
|
|
8
|
+
"description": "Formats a number as Indian currency with Rupee symbol and two decimal places."
|
|
9
|
+
},
|
|
10
|
+
"formatted as currency": {
|
|
11
|
+
"tsExpression": "{value}.toLocaleString('en-IN', { style: 'currency', currency: 'INR', minimumFractionDigits: 2, maximumFractionDigits: 2 })",
|
|
12
|
+
"nullSafe": "typeof {value} === 'number' ? {value}.toLocaleString('en-IN', { style: 'currency', currency: 'INR', minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '--'",
|
|
13
|
+
"description": "Alias for 'formatted as indian currency'."
|
|
14
|
+
},
|
|
15
|
+
"formatted as percentage": {
|
|
16
|
+
"tsExpression": "`${((({value}) ?? 0) * 100).toFixed(2)}%`",
|
|
17
|
+
"nullSafe": "typeof {value} === 'number' ? `${({value} * 100).toFixed(2)}%` : '--'",
|
|
18
|
+
"description": "Multiplies a decimal fraction by 100 and appends %. Input 0.1234 → '12.34%'."
|
|
19
|
+
},
|
|
20
|
+
"show as percentage": {
|
|
21
|
+
"tsExpression": "`${((({value}) ?? 0) * 100).toFixed(2)}%`",
|
|
22
|
+
"nullSafe": "typeof {value} === 'number' ? `${({value} * 100).toFixed(2)}%` : '--'",
|
|
23
|
+
"description": "Alias for 'formatted as percentage'."
|
|
24
|
+
},
|
|
25
|
+
"formatted as date dd mmm yyyy": {
|
|
26
|
+
"tsExpression": "new Date({value}).toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' })",
|
|
27
|
+
"nullSafe": "{value} ? new Date({value}).toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' }) : '--'",
|
|
28
|
+
"description": "Formats an ISO date string or timestamp as '15 Jan 2024'."
|
|
29
|
+
},
|
|
30
|
+
"formatted as date": {
|
|
31
|
+
"tsExpression": "new Date({value}).toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' })",
|
|
32
|
+
"nullSafe": "{value} ? new Date({value}).toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' }) : '--'",
|
|
33
|
+
"description": "Alias for 'formatted as date dd mmm yyyy'."
|
|
34
|
+
},
|
|
35
|
+
"formatted as boolean badge": {
|
|
36
|
+
"tsExpression": null,
|
|
37
|
+
"jsxPattern": "<Text style={{ color: {value} ? '#008675' : '#971b2f', fontWeight: '600' }}>{value} ? 'Yes' : 'No'</Text>",
|
|
38
|
+
"description": "Renders a green/red colored Text badge based on truthy/falsy value. Customize the true/false labels in the spec mapping description."
|
|
39
|
+
},
|
|
40
|
+
"formatted as compact number": {
|
|
41
|
+
"tsExpression": "{value} >= 10_000_000 ? `${({value} / 10_000_000).toFixed(2)} Cr` : {value} >= 100_000 ? `${({value} / 100_000).toFixed(2)} L` : {value}.toLocaleString('en-IN')",
|
|
42
|
+
"nullSafe": "typeof {value} === 'number' ? ({value} >= 10_000_000 ? `${({value} / 10_000_000).toFixed(2)} Cr` : {value} >= 100_000 ? `${({value} / 100_000).toFixed(2)} L` : {value}.toLocaleString('en-IN')) : '--'",
|
|
43
|
+
"description": "Abbreviates large numbers to Indian units: Cr (crore) above 10M, L (lakh) above 100K."
|
|
44
|
+
},
|
|
45
|
+
"formatted as units": {
|
|
46
|
+
"tsExpression": "`${({value} ?? 0).toFixed(3)} units`",
|
|
47
|
+
"nullSafe": "typeof {value} === 'number' ? `${{value}.toFixed(3)} units` : '--'",
|
|
48
|
+
"description": "Formats a number as mutual fund units with 3 decimal places."
|
|
49
|
+
},
|
|
50
|
+
"formatted as nav": {
|
|
51
|
+
"tsExpression": "`\u20b9${({value} ?? 0).toFixed(4)}`",
|
|
52
|
+
"nullSafe": "typeof {value} === 'number' ? `\u20b9${({value}).toFixed(4)}` : '--'",
|
|
53
|
+
"description": "Formats a Net Asset Value with Rupee symbol and 4 decimal places."
|
|
54
|
+
},
|
|
55
|
+
"hidden": {
|
|
56
|
+
"tsExpression": null,
|
|
57
|
+
"jsxPattern": null,
|
|
58
|
+
"description": "Field is used as a key or internal identifier only. Not rendered in JSX. Add as a property on the item object but omit from JSX."
|
|
59
|
+
},
|
|
60
|
+
"unique key": {
|
|
61
|
+
"tsExpression": null,
|
|
62
|
+
"jsxPattern": null,
|
|
63
|
+
"description": "Same as 'hidden' — used as the FlatList keyExtractor key. Not rendered."
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"badgeLabelOverrides": {
|
|
68
|
+
"_comment": "When spec uses 'badge: green for X, red for Y', extract the label pair. Format: { trueLabel: string, falseLabel: string }.",
|
|
69
|
+
"examples": [
|
|
70
|
+
{ "pattern": "green for Purchase, red for Redemption", "trueLabel": "Purchase", "falseLabel": "Redemption" },
|
|
71
|
+
{ "pattern": "green for Active, red for Inactive", "trueLabel": "Active", "falseLabel": "Inactive" },
|
|
72
|
+
{ "pattern": "green for Credit, red for Debit", "trueLabel": "Credit", "falseLabel": "Debit" }
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
"matchingRules": {
|
|
77
|
+
"_comment": "How the skill matches transform keywords against spec mapping text.",
|
|
78
|
+
"caseSensitive": false,
|
|
79
|
+
"strategy": "substring-match",
|
|
80
|
+
"fallback": "If no keyword matches, render the raw value as a string with no transform. Log a WARN."
|
|
81
|
+
}
|
|
82
|
+
}
|