@ngockhoale/ukit 1.1.6
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/CHANGELOG.md +179 -0
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/bin/ukit +30 -0
- package/manifests/platform.full.yaml +1194 -0
- package/package.json +71 -0
- package/scripts/bug/triage.mjs +37 -0
- package/scripts/index/build-index.mjs +35 -0
- package/scripts/index/query-index.mjs +92 -0
- package/scripts/index/refresh-index.mjs +85 -0
- package/scripts/release/verify-release.mjs +56 -0
- package/src/bug/triageBug.js +123 -0
- package/src/cli/adapters.js +148 -0
- package/src/cli/commands/diff.js +51 -0
- package/src/cli/commands/doctor.js +125 -0
- package/src/cli/commands/indexArgs.js +73 -0
- package/src/cli/commands/indexTools.js +509 -0
- package/src/cli/commands/install.js +293 -0
- package/src/cli/commands/memory.js +126 -0
- package/src/cli/commands/status.js +8 -0
- package/src/cli/commands/uninstall.js +51 -0
- package/src/cli/index.js +109 -0
- package/src/context/detectProjectContext.js +49 -0
- package/src/context/detectProviders.js +12 -0
- package/src/core/applyPlan.js +89 -0
- package/src/core/buildPlan.js +228 -0
- package/src/core/compact/index.js +294 -0
- package/src/core/compact/threshold.js +936 -0
- package/src/core/diffPlan.js +73 -0
- package/src/core/ensureGitignore.js +117 -0
- package/src/core/fileOps.js +188 -0
- package/src/core/memory/hygiene.js +160 -0
- package/src/core/memory/index.js +2 -0
- package/src/core/memory/retrieval.js +476 -0
- package/src/core/memory/store.js +202 -0
- package/src/core/metadata.js +132 -0
- package/src/core/migrateLegacy.js +139 -0
- package/src/core/output/index.js +1309 -0
- package/src/core/paths.js +13 -0
- package/src/core/report.js +17 -0
- package/src/core/router/advisor.js +42 -0
- package/src/core/router/index.js +2 -0
- package/src/core/router/router.js +164 -0
- package/src/core/runInstallPipeline.js +365 -0
- package/src/core/runtimeConfig.js +190 -0
- package/src/core/runtimePaths.js +24 -0
- package/src/core/status.js +186 -0
- package/src/core/token/index.js +328 -0
- package/src/core/uninstall.js +246 -0
- package/src/core/validation/confidence.js +89 -0
- package/src/core/validation/index.js +2 -0
- package/src/core/validation/validator.js +165 -0
- package/src/index/buildIndex.js +1392 -0
- package/src/index/gitHooks.js +109 -0
- package/src/index/importResolution.js +377 -0
- package/src/index/languageTools.js +127 -0
- package/src/index/paths.js +27 -0
- package/src/index/queryIndex.js +637 -0
- package/src/index/relatedTests.js +237 -0
- package/src/index/resolveContext.js +345 -0
- package/src/index/routeCatalog.js +258 -0
- package/src/index/taskRouting.js +677 -0
- package/src/index/verificationPlan.js +437 -0
- package/src/manifest/loadManifest.js +22 -0
- package/src/manifest/selectItems.js +78 -0
- package/src/manifest/validateManifest.js +115 -0
- package/src/render/buildVariables.js +39 -0
- package/src/render/renderTemplate.js +44 -0
- package/src/stack/detectStack.js +213 -0
- package/templates/.claude/agents/bug-debugger.md +57 -0
- package/templates/.claude/agents/feature-implementer.md +55 -0
- package/templates/.claude/config/providers.md +25 -0
- package/templates/.claude/hooks/auto-allow-bash.sh +155 -0
- package/templates/.claude/hooks/auto-prune-bash.sh +75 -0
- package/templates/.claude/hooks/block-dangerous.sh +54 -0
- package/templates/.claude/hooks/compress-output.sh +17 -0
- package/templates/.claude/hooks/protect-files.sh +37 -0
- package/templates/.claude/hooks/reinject-context.sh +28 -0
- package/templates/.claude/hooks/session-start.md +13 -0
- package/templates/.claude/hooks/skill-router.sh +1681 -0
- package/templates/.claude/hooks/verification-guard.sh +271 -0
- package/templates/.claude/settings.json +144 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/mce/mc.xsd +75 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/templates/.claude/skills/_shared/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/pack.py +159 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/unpack.py +29 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/validate.py +69 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/validation/base.py +951 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/validation/docx.py +274 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/.claude/skills/_shared/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/.claude/skills/backend-api/SKILL.md +26 -0
- package/templates/.claude/skills/canvas-design/LICENSE.txt +202 -0
- package/templates/.claude/skills/canvas-design/SKILL.md +130 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/templates/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/templates/.claude/skills/code-review/SKILL.md +97 -0
- package/templates/.claude/skills/debugging-toolkit/SKILL.md +156 -0
- package/templates/.claude/skills/delivery/SKILL.md +92 -0
- package/templates/.claude/skills/discover-security/SKILL.md +86 -0
- package/templates/.claude/skills/docker-packaging/SKILL.md +60 -0
- package/templates/.claude/skills/docs-manager/SKILL.md +465 -0
- package/templates/.claude/skills/docs-manager/init-project-docs.sh +70 -0
- package/templates/.claude/skills/docs-manager/templates/README.md.template +50 -0
- package/templates/.claude/skills/docs-manager/templates/agent-roles.md.template +24 -0
- package/templates/.claude/skills/docs-manager/templates/coding-conventions.md.template +28 -0
- package/templates/.claude/skills/docs-manager/templates/memory.md.template +30 -0
- package/templates/.claude/skills/docs-manager/templates/onboarding.md.template +20 -0
- package/templates/.claude/skills/docs-manager/templates/project.md.template +26 -0
- package/templates/.claude/skills/docs-quality/SKILL.md +148 -0
- package/templates/.claude/skills/docx/LICENSE.txt +30 -0
- package/templates/.claude/skills/docx/SKILL.md +197 -0
- package/templates/.claude/skills/docx/docx-js.md +350 -0
- package/templates/.claude/skills/docx/ooxml.md +610 -0
- package/templates/.claude/skills/docx/scripts/__init__.py +1 -0
- package/templates/.claude/skills/docx/scripts/document.py +1276 -0
- package/templates/.claude/skills/docx/scripts/templates/comments.xml +3 -0
- package/templates/.claude/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/templates/.claude/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/templates/.claude/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/templates/.claude/skills/docx/scripts/templates/people.xml +3 -0
- package/templates/.claude/skills/docx/scripts/utilities.py +374 -0
- package/templates/.claude/skills/duraone/SKILL.md +204 -0
- package/templates/.claude/skills/duraone/references/backend.md +636 -0
- package/templates/.claude/skills/duraone/references/frontend.md +1506 -0
- package/templates/.claude/skills/duraone/references/sql.md +631 -0
- package/templates/.claude/skills/duraone/references/workflow.md +520 -0
- package/templates/.claude/skills/executing-plans/SKILL.md +76 -0
- package/templates/.claude/skills/file-organizer/SKILL.md +433 -0
- package/templates/.claude/skills/frontend/SKILL.md +26 -0
- package/templates/.claude/skills/frontend-design/LICENSE.txt +177 -0
- package/templates/.claude/skills/frontend-design/SKILL.md +42 -0
- package/templates/.claude/skills/frontend-vue/SKILL.md +127 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Box.vue +137 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Button.vue +93 -0
- package/templates/.claude/skills/frontend-vue/components/Control/ButtonBar.vue +29 -0
- package/templates/.claude/skills/frontend-vue/components/Control/ButtonFloat.vue +62 -0
- package/templates/.claude/skills/frontend-vue/components/Control/CheckButton.vue +75 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Checkbox.vue +58 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Datetime.vue +148 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Dropdownlist.vue +156 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Input.vue +106 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Label.vue +38 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Master/BoxColumn.vue +24 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Popup/Confirm.vue +33 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Popup/Info.vue +32 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Popup/ModalInfo.vue +39 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Popup/Reject.vue +64 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Tag.vue +82 -0
- package/templates/.claude/skills/frontend-vue/components/Control/Upload.vue +61 -0
- package/templates/.claude/skills/frontend-vue/components/ControlMobile/Dropdownlist.vue +103 -0
- package/templates/.claude/skills/frontend-vue/components/ControlMobile/PagingBar.vue +108 -0
- package/templates/.claude/skills/frontend-vue/components/ControlMobile/UploadImage.vue +137 -0
- package/templates/.claude/skills/frontend-vue/components/Grid/AG.vue +806 -0
- package/templates/.claude/skills/frontend-vue/components/Grid/AntTable.vue +253 -0
- package/templates/.claude/skills/frontend-vue/components/Grid/CustomDropdownEditor.vue +43 -0
- package/templates/.claude/skills/frontend-vue/components/Grid/CustomDropdownEditorEnable.vue +55 -0
- package/templates/.claude/skills/frontend-vue/components/Grid/HtmlTable.vue +40 -0
- package/templates/.claude/skills/frontend-vue/components/PDFViewer.vue +25 -0
- package/templates/.claude/skills/frontend-vue/components/Panel/FormView.vue +309 -0
- package/templates/.claude/skills/frontend-vue/components/Partial/Footer.vue +23 -0
- package/templates/.claude/skills/frontend-vue/components/Partial/Header.vue +265 -0
- package/templates/.claude/skills/frontend-vue/components/Partial/Sidebar.vue +122 -0
- package/templates/.claude/skills/frontend-vue/components/Template.vue +16 -0
- package/templates/.claude/skills/frontend-vue/components/View/Form.vue +89 -0
- package/templates/.claude/skills/frontend-vue/composables/indexDBStore.js +140 -0
- package/templates/.claude/skills/frontend-vue/composables/masterApi.js +362 -0
- package/templates/.claude/skills/frontend-vue/composables/state.js +578 -0
- package/templates/.claude/skills/frontend-vue/composables/useRequest.js +221 -0
- package/templates/.claude/skills/frontend-vue/composables/useSession.js +179 -0
- package/templates/.claude/skills/frontend-vue/composables/useTranslation.js +54 -0
- package/templates/.claude/skills/frontend-vue/composables/useWebSocket.js +257 -0
- package/templates/.claude/skills/frontend-vue/composables/userObj.js +111 -0
- package/templates/.claude/skills/frontend-vue/composables/utils.js +322 -0
- package/templates/.claude/skills/frontend-vue/reference/composables-example.vue +320 -0
- package/templates/.claude/skills/frontend-vue/reference/form-example.vue +183 -0
- package/templates/.claude/skills/frontend-vue/reference/grid-example.vue +147 -0
- package/templates/.claude/skills/frontend-vue/reference/masterdata-example/[id].vue +106 -0
- package/templates/.claude/skills/frontend-vue/reference/masterdata-example/index.vue +58 -0
- package/templates/.claude/skills/frontend-vue/reference/popup-example.vue +159 -0
- package/templates/.claude/skills/pdf/LICENSE.txt +30 -0
- package/templates/.claude/skills/pdf/SKILL.md +294 -0
- package/templates/.claude/skills/pdf/forms.md +205 -0
- package/templates/.claude/skills/pdf/reference.md +612 -0
- package/templates/.claude/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/templates/.claude/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/templates/.claude/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/templates/.claude/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/templates/.claude/skills/pdf/scripts/create_validation_image.py +41 -0
- package/templates/.claude/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/templates/.claude/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/templates/.claude/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/templates/.claude/skills/pdf-processing/SKILL.md +107 -0
- package/templates/.claude/skills/pdf-processing-pro/FORMS.md +610 -0
- package/templates/.claude/skills/pdf-processing-pro/OCR.md +137 -0
- package/templates/.claude/skills/pdf-processing-pro/SKILL.md +296 -0
- package/templates/.claude/skills/pdf-processing-pro/TABLES.md +626 -0
- package/templates/.claude/skills/pdf-processing-pro/scripts/analyze_form.py +307 -0
- package/templates/.claude/skills/postgres/SKILL.md +69 -0
- package/templates/.claude/skills/postgres/reference/fn_get_examples.sql +208 -0
- package/templates/.claude/skills/postgres/reference/fn_rpt_examples.sql +239 -0
- package/templates/.claude/skills/postgres/reference/utility_functions.sql +94 -0
- package/templates/.claude/skills/pptx/LICENSE.txt +30 -0
- package/templates/.claude/skills/pptx/SKILL.md +484 -0
- package/templates/.claude/skills/pptx/html2pptx.md +625 -0
- package/templates/.claude/skills/pptx/ooxml.md +427 -0
- package/templates/.claude/skills/pptx/scripts/html2pptx.js +979 -0
- package/templates/.claude/skills/pptx/scripts/inventory.py +1020 -0
- package/templates/.claude/skills/pptx/scripts/rearrange.py +231 -0
- package/templates/.claude/skills/pptx/scripts/replace.py +385 -0
- package/templates/.claude/skills/pptx/scripts/thumbnail.py +450 -0
- package/templates/.claude/skills/repo-maintenance/SKILL.md +97 -0
- package/templates/.claude/skills/research/EXAMPLES.md +434 -0
- package/templates/.claude/skills/research/REFERENCE.md +399 -0
- package/templates/.claude/skills/research/SKILL.md +136 -0
- package/templates/.claude/skills/root-cause-tracing/SKILL.md +174 -0
- package/templates/.claude/skills/root-cause-tracing/find-polluter.sh +63 -0
- package/templates/.claude/skills/sharing-skills/SKILL.md +194 -0
- package/templates/.claude/skills/sql-optimization-patterns/SKILL.md +493 -0
- package/templates/.claude/skills/subagent-driven-development/SKILL.md +189 -0
- package/templates/.claude/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/templates/.claude/skills/systematic-debugging/SKILL.md +295 -0
- package/templates/.claude/skills/systematic-debugging/test-academic.md +14 -0
- package/templates/.claude/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/templates/.claude/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/templates/.claude/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/templates/.claude/skills/test-driven-development/SKILL.md +364 -0
- package/templates/.claude/skills/testing-anti-patterns/SKILL.md +302 -0
- package/templates/.claude/skills/testing-quality/SKILL.md +97 -0
- package/templates/.claude/skills/verification-before-completion/SKILL.md +139 -0
- package/templates/.claude/skills/webapp-testing/LICENSE.txt +202 -0
- package/templates/.claude/skills/webapp-testing/SKILL.md +96 -0
- package/templates/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
- package/templates/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/templates/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/templates/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
- package/templates/.claude/ukit/index/build-index.mjs +28 -0
- package/templates/.claude/ukit/index/cache-utils.mjs +140 -0
- package/templates/.claude/ukit/index/lib/index-core.mjs +2800 -0
- package/templates/.claude/ukit/index/query-index.mjs +150 -0
- package/templates/.claude/ukit/index/refresh-index.mjs +57 -0
- package/templates/.claude/ukit/index/reset-auto-permissions.mjs +76 -0
- package/templates/.claude/ukit/index/resolve-context.mjs +279 -0
- package/templates/.claude/ukit/index/route-catalog.mjs +258 -0
- package/templates/.claude/ukit/index/route-task.mjs +1994 -0
- package/templates/.claude/ukit/index/triage.mjs +133 -0
- package/templates/.claude/ukit/index/verify-context.mjs +689 -0
- package/templates/.claude/ukit/runtime/compact-threshold.mjs +1013 -0
- package/templates/.claude/ukit/runtime/output-compression.mjs +1340 -0
- package/templates/.claude/ukit/runtime/reinject-context.mjs +874 -0
- package/templates/.claude/ukit/runtime/token-utils.mjs +500 -0
- package/templates/.codex/README.md +83 -0
- package/templates/.codex/settings.json +187 -0
- package/templates/.gitignore +75 -0
- package/templates/AGENTS.md +116 -0
- package/templates/CLAUDE.md +93 -0
- package/templates/adapter-presets/antigravity/README.md +22 -0
- package/templates/adapter-presets/antigravity/rules.md +49 -0
- package/templates/adapter-presets/claude/settings.local.json +42 -0
- package/templates/adapter-presets/codex/settings.local.json +6 -0
- package/templates/adapter-presets/opencode/opencode.template.json +1 -0
- package/templates/docs/BUGFIX.md +20 -0
- package/templates/docs/BUG_INDEX.md +12 -0
- package/templates/docs/BUG_METRICS.md +7 -0
- package/templates/docs/BUG_TEMPLATE.md +13 -0
- package/templates/docs/CODE_MAP.md +35 -0
- package/templates/docs/INSTALL.md +113 -0
- package/templates/docs/MEMORY.md +49 -0
- package/templates/docs/PROJECT.md +50 -0
- package/templates/docs/UKIT_USAGE_GUIDE.md +147 -0
- package/templates/docs/WORKLOG.md +10 -0
- package/templates/ukit/README.md +14 -0
- package/templates/ukit/storage/cache/compact-history.json +3 -0
- package/templates/ukit/storage/cache/compact-pressure.json +1 -0
- package/templates/ukit/storage/cache/output-history.json +3 -0
- package/templates/ukit/storage/cache/prompt-cache.json +3 -0
- package/templates/ukit/storage/config.json +37 -0
- package/templates/ukit/storage/memory/projects/.gitkeep +2 -0
- package/templates/ukit/storage/memory/sessions/.gitkeep +0 -0
- package/templates/ukit/storage/memory/user.json +5 -0
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
# DuraOne Workflow Reference
|
|
2
|
+
## Luồng Hoạt Động Toàn Bộ Dự Án
|
|
3
|
+
|
|
4
|
+
> Mô tả cách một tính năng đi từ ý tưởng → SQL → Backend → Frontend → Deploy.
|
|
5
|
+
> Đọc file này khi thiết kế tính năng mới hoặc cần hiểu toàn bộ data flow.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## MỤC LỤC
|
|
10
|
+
1. [Kiến Trúc Tổng Quan](#1-kiến-trúc-tổng-quan)
|
|
11
|
+
2. [Data Flow: FE → BE → DB](#2-data-flow)
|
|
12
|
+
3. [Luồng Tạo Tính Năng Mới](#3-luồng-tạo-tính-năng-mới)
|
|
13
|
+
4. [Luồng CRUD Chuẩn](#4-luồng-crud-chuẩn)
|
|
14
|
+
5. [Luồng Approval / Workflow Status](#5-luồng-approval--workflow-status)
|
|
15
|
+
6. [Luồng Upload File](#6-luồng-upload-file)
|
|
16
|
+
7. [Luồng Authentication](#7-luồng-authentication)
|
|
17
|
+
8. [Luồng Deploy QAS → PRD](#8-luồng-deploy-qas--prd)
|
|
18
|
+
9. [Environment Switch](#9-environment-switch)
|
|
19
|
+
10. [Checklist Tạo Tính Năng](#10-checklist-tạo-tính-năng)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Kiến Trúc Tổng Quan
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
27
|
+
│ BROWSER / MOBILE │
|
|
28
|
+
│ Nuxt 3 (Vue 3 Options API) │
|
|
29
|
+
│ - pages/ │
|
|
30
|
+
│ - components/Control, Grid, Panel │
|
|
31
|
+
│ - composables/ (auto-imported) │
|
|
32
|
+
└──────────────────────────┬──────────────────────────────────┘
|
|
33
|
+
│ HTTPS + GZIP compression
|
|
34
|
+
│ Axios → useRequest.js
|
|
35
|
+
▼
|
|
36
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
37
|
+
│ PYTHON SANIC API │
|
|
38
|
+
│ app.py + mainapp/lib/ │
|
|
39
|
+
│ │
|
|
40
|
+
│ Generic: /api/select /api/save /api/delete /api/run_proc │
|
|
41
|
+
│ Custom: /api/[feature]/[action] │
|
|
42
|
+
│ Auth: /user/login │
|
|
43
|
+
└──────────────────────────┬──────────────────────────────────┘
|
|
44
|
+
│ asyncpg (connection pool + SSL)
|
|
45
|
+
▼
|
|
46
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
47
|
+
│ POSTGRESQL │
|
|
48
|
+
│ Schema: qas (test) | Schema: prd (production) │
|
|
49
|
+
│ │
|
|
50
|
+
│ Tables — raw data storage │
|
|
51
|
+
│ Views — v_* (read layer, computed fields, joins) │
|
|
52
|
+
│ Functions — fn_* (filtered queries, complex logic) │
|
|
53
|
+
│ Procs — sp_* (running numbers, cascades, audits) │
|
|
54
|
+
└─────────────────────────────────────────────────────────────┘
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 2. Data Flow
|
|
60
|
+
|
|
61
|
+
### READ (FE → DB)
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Vue Page (created/mounted)
|
|
65
|
+
│
|
|
66
|
+
├── get_data() gọi request("/select", data, "get")
|
|
67
|
+
│ data = { schema: get_schema(), table: "v_entity", conditions: JSON.stringify({...}), order_by: [...] }
|
|
68
|
+
│
|
|
69
|
+
├── useRequest.js: GZIP compress → Axios GET → Sanic /api/select
|
|
70
|
+
│
|
|
71
|
+
├── Sanic: parse request → build SQL → asyncpg.fetch()
|
|
72
|
+
│ SELECT * FROM {schema}.{table} WHERE {conditions} ORDER BY {order_by}
|
|
73
|
+
│
|
|
74
|
+
├── PostgreSQL: execute query on view → return rows
|
|
75
|
+
│
|
|
76
|
+
├── Sanic: GZIP compress response → return JSON
|
|
77
|
+
│
|
|
78
|
+
└── Vue: decompress → this.rows = result
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### WRITE (FE → DB)
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Vue Page (save button click)
|
|
85
|
+
│
|
|
86
|
+
├── validate() — check required fields
|
|
87
|
+
│
|
|
88
|
+
├── request("/save", { table, key_array, ...workingObj })
|
|
89
|
+
│
|
|
90
|
+
├── Sanic /api/save:
|
|
91
|
+
│ IF id_field == '': DB_Helper.insert(table, obj) ← uuid varchar default ''
|
|
92
|
+
│ IF id_field != '': DB_Helper.update(table, obj, key_field)
|
|
93
|
+
│
|
|
94
|
+
└── PostgreSQL: INSERT or UPDATE → return new id
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### RUN PROCEDURE (FE → DB)
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
request("/run_proc", { schema, proc_name, params: { ... } })
|
|
101
|
+
│
|
|
102
|
+
├── Sanic /api/run_proc
|
|
103
|
+
│
|
|
104
|
+
└── PostgreSQL: SELECT * FROM {schema}.{proc_name}($1, $2, ...)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 3. Luồng Tạo Tính Năng Mới
|
|
110
|
+
|
|
111
|
+
### Bước 1: Thiết Kế DB Layer
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
a) Tạo/update table nếu cần (xem chi tiết template tại references/sql.md → mục 7):
|
|
115
|
+
-- Chỉ dùng varchar / numeric / boolean. Không NULL, luôn có default.
|
|
116
|
+
create table qas.[entity] (
|
|
117
|
+
id_[entity] varchar default uuid_in(overlay(
|
|
118
|
+
overlay(md5(random()::text || ':' || random()::text) placing '4' from 13) placing
|
|
119
|
+
to_hex(floor(random() * (11 - 8 + 1) + 8)::int)::text from 17)::cstring)
|
|
120
|
+
constraint [entity]_pkey primary key,
|
|
121
|
+
-- business fields (varchar/numeric/boolean)
|
|
122
|
+
is_deleted boolean default false,
|
|
123
|
+
created_by varchar default '',
|
|
124
|
+
created_at varchar default TO_CHAR(date_trunc('second', now() AT TIME ZONE 'Asia/Ho_Chi_Minh'),
|
|
125
|
+
'YYYY-MM-DD HH24:MI:SS')::character varying
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
b) Tạo view (luôn cần):
|
|
129
|
+
CREATE OR REPLACE VIEW qas.v_[entity] AS
|
|
130
|
+
SELECT
|
|
131
|
+
e.*,
|
|
132
|
+
-- computed fields
|
|
133
|
+
-- joined fields
|
|
134
|
+
-- boolean flags (can_edit, is_locked, etc.)
|
|
135
|
+
-- json aggregation cho sub-records
|
|
136
|
+
FROM qas.[entity] e
|
|
137
|
+
LEFT JOIN ... ON ...
|
|
138
|
+
WHERE e.is_deleted = FALSE;
|
|
139
|
+
|
|
140
|
+
c) Tạo function nếu cần filter phức tạp:
|
|
141
|
+
CREATE OR REPLACE FUNCTION qas.fn_get_[entity](_param VARCHAR)
|
|
142
|
+
RETURNS SETOF qas.v_[entity] AS ...
|
|
143
|
+
|
|
144
|
+
d) Tạo stored proc nếu cần business logic:
|
|
145
|
+
CREATE OR REPLACE FUNCTION qas.sp_[action]_[entity](_id VARCHAR)
|
|
146
|
+
RETURNS JSON AS ...
|
|
147
|
+
|
|
148
|
+
e) Mirror sang prd schema (thay qas. → prd.)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Bước 2: Backend (chỉ khi cần custom)
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
Nếu generic /api/select, /api/save, /api/delete đủ dùng → SKIP
|
|
155
|
+
|
|
156
|
+
Nếu cần custom:
|
|
157
|
+
a) Thêm route vào mainapp/lib/v2_api.py:
|
|
158
|
+
@b_api.route("/api/[feature]/[action]", methods=["POST"])
|
|
159
|
+
async def [action](request):
|
|
160
|
+
...
|
|
161
|
+
|
|
162
|
+
b) Business logic trong route handler
|
|
163
|
+
c) Gọi db.execute() hoặc db.execute_void()
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Bước 3: Frontend
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
a) masterApi.js — thêm get functions:
|
|
170
|
+
export const get_[entity]_by_id = async (id) => { ... }
|
|
171
|
+
export const get_[entity]_list_dropdown = async () => { ... }
|
|
172
|
+
|
|
173
|
+
b) Tạo page files:
|
|
174
|
+
pages/[Feature]/[EntityList].vue — danh sách
|
|
175
|
+
pages/[Feature]/[EntityForm].vue — form detail/edit
|
|
176
|
+
|
|
177
|
+
c) Trong page:
|
|
178
|
+
- created(): auth check → load data
|
|
179
|
+
- data(): workingObj, rows, dropdowns, flags
|
|
180
|
+
- computed: is_locked, can_save, etc.
|
|
181
|
+
- methods: get_data, save, validate, load_dropdowns
|
|
182
|
+
|
|
183
|
+
d) Reuse Control components (KHÔNG tự tạo input raw)
|
|
184
|
+
e) Reuse GridAG cho danh sách
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Bước 4: Route & Menu
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
a) Thêm menu item trong state.js → menu()
|
|
191
|
+
b) Thêm authorization rule nếu cần
|
|
192
|
+
c) Test auth redirect
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 4. Luồng CRUD Chuẩn
|
|
198
|
+
|
|
199
|
+
### CREATE (New Record)
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
FE: workingObj.id_[entity] = '' (default trong data() — uuid varchar)
|
|
203
|
+
↓ user fills form
|
|
204
|
+
↓ save() → validate() → request("/save", { id_[entity]: '', ... })
|
|
205
|
+
BE: detect id == '' → DB_Helper.insert()
|
|
206
|
+
DB: INSERT → uuid auto-generated → RETURNING id_[entity]
|
|
207
|
+
FE: redirect to form với id mới hoặc show success
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### READ (Load Record)
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
FE: created() → load_by_id(this.$route.query.id)
|
|
214
|
+
↓ get_[entity]_by_id(id) trong masterApi.js
|
|
215
|
+
↓ request("/select", { table: "v_[entity]", conditions: { id_[entity]: id } }, "get")
|
|
216
|
+
DB: SELECT * FROM qas.v_[entity] WHERE id_[entity] = ?
|
|
217
|
+
FE: this.workingObj = result[0] || {}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### UPDATE (Save Existing)
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
FE: workingObj.id_[entity] != '' (loaded từ DB — uuid string)
|
|
224
|
+
↓ user edits
|
|
225
|
+
↓ save() → validate() → request("/save", { id_[entity]: 'uuid-...', ... })
|
|
226
|
+
BE: detect id != '' → DB_Helper.update()
|
|
227
|
+
DB: UPDATE [entity] SET ... WHERE id_[entity] = 'uuid-...'
|
|
228
|
+
FE: show_message("success", "Saved!")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### DELETE (Soft Delete — preferred)
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
FE: confirm dialog → onConfirmDelete()
|
|
235
|
+
↓ request("/save", { table: "[entity]", key_array: ["id_[entity]"], id_[entity]: id, is_deleted: true })
|
|
236
|
+
DB: UPDATE [entity] SET is_deleted = TRUE WHERE id_[entity] = ?
|
|
237
|
+
FE: reload list
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 5. Luồng Approval / Workflow Status
|
|
243
|
+
|
|
244
|
+
Pattern cho các tính năng có trạng thái (draft → pending → approved/rejected):
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
Status Flow:
|
|
248
|
+
draft ──► pending_approval ──► approved
|
|
249
|
+
│ │
|
|
250
|
+
└──► rejected ◄─────┘
|
|
251
|
+
│
|
|
252
|
+
└──► draft (resubmit)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**DB Design:**
|
|
256
|
+
```sql
|
|
257
|
+
-- View: boolean flags từ status
|
|
258
|
+
CASE WHEN status = 'draft' THEN TRUE ELSE FALSE END AS can_edit,
|
|
259
|
+
CASE WHEN status = 'draft' THEN TRUE ELSE FALSE END AS can_submit,
|
|
260
|
+
CASE WHEN status = 'pending_approval' THEN TRUE ELSE FALSE END AS can_approve,
|
|
261
|
+
CASE WHEN status = 'approved' THEN TRUE ELSE FALSE END AS is_locked,
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**FE Pattern:**
|
|
265
|
+
```javascript
|
|
266
|
+
computed: {
|
|
267
|
+
is_locked() {
|
|
268
|
+
return !this.workingObj.can_edit;
|
|
269
|
+
},
|
|
270
|
+
show_submit_btn() {
|
|
271
|
+
return this.workingObj.can_submit;
|
|
272
|
+
},
|
|
273
|
+
show_approve_btn() {
|
|
274
|
+
return this.workingObj.can_approve;
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
methods: {
|
|
278
|
+
async submit() {
|
|
279
|
+
await request("/save", {
|
|
280
|
+
table: "[entity]",
|
|
281
|
+
key_array: ["id_[entity]"],
|
|
282
|
+
id_[entity]: this.workingObj.id_[entity],
|
|
283
|
+
status: "pending_approval",
|
|
284
|
+
});
|
|
285
|
+
await this.load_by_id(this.workingObj.id_[entity]); // reload
|
|
286
|
+
},
|
|
287
|
+
async approve() {
|
|
288
|
+
await request_origin("/api/[entity]/approve", {
|
|
289
|
+
id_[entity]: this.workingObj.id_[entity],
|
|
290
|
+
schema: get_schema(),
|
|
291
|
+
username: state.username, // ✅ luôn truyền username cho custom approve endpoints
|
|
292
|
+
});
|
|
293
|
+
await this.load_by_id(this.workingObj.id_[entity]);
|
|
294
|
+
},
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 6. Luồng Upload File
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
FE:
|
|
304
|
+
1. User selects file → fileInput change event
|
|
305
|
+
2. preview (optional)
|
|
306
|
+
3. upload_file(file, folder)
|
|
307
|
+
↓ FormData.append("file", file)
|
|
308
|
+
↓ requestForm("/api/upload_to_cloud", formData)
|
|
309
|
+
4. save URL vào workingObj.file_url
|
|
310
|
+
|
|
311
|
+
BE:
|
|
312
|
+
/api/upload_to_cloud
|
|
313
|
+
↓ request.files.get("file")
|
|
314
|
+
↓ google_storage.upload_blob(...)
|
|
315
|
+
↓ return { url: "https://storage.googleapis.com/..." }
|
|
316
|
+
|
|
317
|
+
FE after upload:
|
|
318
|
+
workingObj.file_url = result.url
|
|
319
|
+
↓ save workingObj (URL stored in DB)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Multiple Files Pattern:**
|
|
323
|
+
```javascript
|
|
324
|
+
data() {
|
|
325
|
+
return {
|
|
326
|
+
fileListToUpload: {
|
|
327
|
+
0: [], // indexed by media type
|
|
328
|
+
1: [],
|
|
329
|
+
2: [],
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
methods: {
|
|
334
|
+
async upload_all_files() {
|
|
335
|
+
for (const [index, files] of Object.entries(this.fileListToUpload)) {
|
|
336
|
+
for (const file of files) {
|
|
337
|
+
const url = await this.upload_file(file, `entity/${index}`);
|
|
338
|
+
await request("/save", {
|
|
339
|
+
table: "[entity]_file",
|
|
340
|
+
key_array: ["id_file"],
|
|
341
|
+
id_file: '',
|
|
342
|
+
id_entity: this.workingObj.id_entity,
|
|
343
|
+
file_type: index,
|
|
344
|
+
file_url: url,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 7. Luồng Authentication
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
Login:
|
|
358
|
+
FE: ms_authen/login.vue → requestLogin({ username, password })
|
|
359
|
+
BE: /user/login → verify → return { token, username, usergroup, ... }
|
|
360
|
+
FE: setSession("user_data", response.data) → redirect to homepage
|
|
361
|
+
|
|
362
|
+
Every Request:
|
|
363
|
+
useRequest.js: read session → attach token to headers
|
|
364
|
+
Sanic middleware: verify token
|
|
365
|
+
If invalid: return 401 → FE redirect to login
|
|
366
|
+
|
|
367
|
+
Per-page Auth:
|
|
368
|
+
created() {
|
|
369
|
+
if (!authorize_menu(this.$route.fullPath)) {
|
|
370
|
+
this.$router.push(state.homepage);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
authorize_menu():
|
|
375
|
+
- reads state.usergroup
|
|
376
|
+
- checks menu() structure for allowed paths per group
|
|
377
|
+
- returns true/false
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## 8. Luồng Deploy QAS → PRD
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
1. Test on QAS:
|
|
386
|
+
- Run SQL on qas schema: psql $QAS -f *.sql
|
|
387
|
+
- Deploy BE to QAS server: ./deploy_qas.sh
|
|
388
|
+
- Deploy FE to QAS: yarn generate → upload to GCS/CDN
|
|
389
|
+
- Test all features
|
|
390
|
+
|
|
391
|
+
2. Deploy to PRD:
|
|
392
|
+
- Run SQL on prd schema (same files, different schema)
|
|
393
|
+
- Deploy BE: ./deploy_prd.sh
|
|
394
|
+
- Deploy FE: APP_ENV=prd yarn generate → upload
|
|
395
|
+
- Smoke test
|
|
396
|
+
|
|
397
|
+
3. Rollback khi deploy lỗi:
|
|
398
|
+
SQL (view / function / stored proc):
|
|
399
|
+
- Chạy lại file SQL version cũ — CREATE OR REPLACE nên safe
|
|
400
|
+
- psql $PRD_CONN -f SQL/duraone/prd/view/v_entity_OLD.sql
|
|
401
|
+
|
|
402
|
+
SQL (ALTER TABLE — table schema change):
|
|
403
|
+
⚠️ PHẢI backup trước khi ALTER:
|
|
404
|
+
pg_dump -t prd.table_name $PRD_CONN > backup_table_name_$(date +%Y%m%d).sql
|
|
405
|
+
Nếu lỗi → reverse bằng ALTER TABLE ngược lại
|
|
406
|
+
|
|
407
|
+
BE (Docker / Cloud Run):
|
|
408
|
+
Rollback về image tag trước:
|
|
409
|
+
gcloud run deploy duraone-prd --image=gcr.io/project/duraone-prd:PREV_TAG
|
|
410
|
+
|
|
411
|
+
FE (GCS / CDN):
|
|
412
|
+
Re-upload build cũ từ artifact storage hoặc re-deploy commit trước
|
|
413
|
+
|
|
414
|
+
Deploy Script Pattern:
|
|
415
|
+
deploy_qas.sh:
|
|
416
|
+
export APP_ENV=qas
|
|
417
|
+
docker build -t duraone-qas .
|
|
418
|
+
docker push gcr.io/project/duraone-qas
|
|
419
|
+
gcloud run deploy duraone-qas --image=...
|
|
420
|
+
|
|
421
|
+
SQL Deploy Pattern:
|
|
422
|
+
# Apply theo thứ tự: table → view → function → stored proc
|
|
423
|
+
psql $CONN -f SQL/duraone/qas/view/v_entity.sql
|
|
424
|
+
psql $CONN -f SQL/duraone/qas/function/fn_get_entity.sql
|
|
425
|
+
psql $CONN -f SQL/duraone/qas/store/sp_action_entity.sql
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## 9. Environment Switch
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
// FE: state.js
|
|
434
|
+
export const get_schema = () => {
|
|
435
|
+
// ✅ Ưu tiên 1: Nuxt runtime config (RECOMMENDED — không phụ thuộc hostname)
|
|
436
|
+
// Setup trong nuxt.config.ts:
|
|
437
|
+
// runtimeConfig: { public: { appEnv: process.env.APP_ENV || 'qas' } }
|
|
438
|
+
// Deploy PRD: set env var APP_ENV=prd
|
|
439
|
+
try {
|
|
440
|
+
const runtimeConfig = useRuntimeConfig();
|
|
441
|
+
if (runtimeConfig?.public?.appEnv === 'prd') return 'prd';
|
|
442
|
+
} catch (_) { /* ignore nếu useRuntimeConfig chưa sẵn */ }
|
|
443
|
+
|
|
444
|
+
// Ưu tiên 2: Hostname detection (fallback — chỉ đáng tin khi domain chứa "prd")
|
|
445
|
+
// ⚠️ CẢNH BÁO: Nếu domain PRD không chứa "prd" hay "production" → sẽ trả về "qas"
|
|
446
|
+
// → query sai schema mà không có lỗi. Luôn set APP_ENV thay vì dựa vào hostname.
|
|
447
|
+
const hostname = window.location.hostname;
|
|
448
|
+
if (hostname.includes("prd") || hostname.includes("production")) {
|
|
449
|
+
return "prd";
|
|
450
|
+
}
|
|
451
|
+
return "qas"; // default
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
export const baseurl = () => {
|
|
455
|
+
const hostname = window.location.hostname;
|
|
456
|
+
if (hostname === "localhost" || hostname === "127.0.0.1") {
|
|
457
|
+
return "http://localhost:8000/";
|
|
458
|
+
}
|
|
459
|
+
return "/"; // relative path cho production
|
|
460
|
+
};
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
// nuxt.config.ts — cần thêm config này để get_schema() hoạt động đúng trên PRD
|
|
465
|
+
export default defineNuxtConfig({
|
|
466
|
+
runtimeConfig: {
|
|
467
|
+
public: {
|
|
468
|
+
appEnv: process.env.APP_ENV || 'qas', // set APP_ENV=prd khi deploy PRD
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
```python
|
|
475
|
+
# BE: config.py
|
|
476
|
+
def get_schema() -> str:
|
|
477
|
+
env = os.environ.get("APP_ENV", "local")
|
|
478
|
+
return "prd" if env == "prd" else "qas"
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## 10. Checklist Tạo Tính Năng
|
|
484
|
+
|
|
485
|
+
Dùng checklist này mỗi khi tạo tính năng mới:
|
|
486
|
+
|
|
487
|
+
### DB Layer
|
|
488
|
+
- [ ] Table đã có `id_[entity]`, audit fields (`created_by`, `created_at`, `is_deleted`)
|
|
489
|
+
- [ ] View `qas.v_[entity]` có `COALESCE` cho numeric, boolean flags (`can_edit`, `is_locked`)
|
|
490
|
+
- [ ] View có JSON aggregation cho sub-records nếu cần
|
|
491
|
+
- [ ] Function `fn_get_*` nếu cần filter phức tạp
|
|
492
|
+
- [ ] Stored proc `sp_*` nếu cần running number / cascade
|
|
493
|
+
- [ ] Mirror sang `prd` schema
|
|
494
|
+
|
|
495
|
+
### Backend
|
|
496
|
+
- [ ] Generic endpoints đủ dùng? (thường là có)
|
|
497
|
+
- [ ] Custom endpoint nếu cần business logic đặc biệt
|
|
498
|
+
- [ ] Error handling trả về `{ success, message }`
|
|
499
|
+
|
|
500
|
+
### Frontend
|
|
501
|
+
- [ ] `masterApi.js` có `get_[entity]_by_id()` và `get_[entity]_list_dropdown()`
|
|
502
|
+
- [ ] List page: filter + GridAG + on_row_click navigate
|
|
503
|
+
- [ ] Form page: workingObj, validate(), save(), is_locked computed
|
|
504
|
+
- [ ] Auth check ở `created()`
|
|
505
|
+
- [ ] `state.page_header` set ở `created()`
|
|
506
|
+
- [ ] Dùng Control components (KHÔNG raw input)
|
|
507
|
+
- [ ] Dropdown data format: `{ value, label }` — load qua `get*List()` pattern với `convertToDropdownValue()`
|
|
508
|
+
- [ ] **Datetime dùng `dayjs()`** — KHÔNG dùng `new Date()`, `Date.now()`, `.getFullYear()`
|
|
509
|
+
- [ ] Boolean flags từ DB (`can_edit`, `is_locked`) drive UI state
|
|
510
|
+
- [ ] File upload nếu cần
|
|
511
|
+
|
|
512
|
+
### Menu & Auth
|
|
513
|
+
- [ ] Menu item thêm vào `state.js → menu()`
|
|
514
|
+
- [ ] Permission rules cho usergroup
|
|
515
|
+
|
|
516
|
+
### Test
|
|
517
|
+
- [ ] Test trên QAS schema
|
|
518
|
+
- [ ] Test create, read, update, delete
|
|
519
|
+
- [ ] Test approval flow nếu có
|
|
520
|
+
- [ ] Test file upload nếu có
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: executing-plans
|
|
3
|
+
description: Use when partner provides a complete implementation plan to execute in controlled batches with review checkpoints - loads plan, reviews critically, executes tasks in batches, reports for review between batches
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Executing Plans
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Load plan, review critically, execute tasks in batches, report for review between batches.
|
|
11
|
+
|
|
12
|
+
**Core principle:** Batch execution with checkpoints for architect review.
|
|
13
|
+
|
|
14
|
+
**Announce at start:** "I'm using the executing-plans skill to implement this plan."
|
|
15
|
+
|
|
16
|
+
## The Process
|
|
17
|
+
|
|
18
|
+
### Step 1: Load and Review Plan
|
|
19
|
+
1. Read plan file
|
|
20
|
+
2. Review critically - identify any questions or concerns about the plan
|
|
21
|
+
3. If concerns: Raise them with your human partner before starting
|
|
22
|
+
4. If no concerns: Create TodoWrite and proceed
|
|
23
|
+
|
|
24
|
+
### Step 2: Execute Batch
|
|
25
|
+
**Default: First 3 tasks**
|
|
26
|
+
|
|
27
|
+
For each task:
|
|
28
|
+
1. Mark as in_progress
|
|
29
|
+
2. Follow each step exactly (plan has bite-sized steps)
|
|
30
|
+
3. Run verifications as specified
|
|
31
|
+
4. Mark as completed
|
|
32
|
+
|
|
33
|
+
### Step 3: Report
|
|
34
|
+
When batch complete:
|
|
35
|
+
- Show what was implemented
|
|
36
|
+
- Show verification output
|
|
37
|
+
- Say: "Ready for feedback."
|
|
38
|
+
|
|
39
|
+
### Step 4: Continue
|
|
40
|
+
Based on feedback:
|
|
41
|
+
- Apply changes if needed
|
|
42
|
+
- Execute next batch
|
|
43
|
+
- Repeat until complete
|
|
44
|
+
|
|
45
|
+
### Step 5: Complete Development
|
|
46
|
+
|
|
47
|
+
After all tasks complete and verified:
|
|
48
|
+
- Announce: "I'm using the finishing-a-development-branch skill to complete this work."
|
|
49
|
+
- **REQUIRED SUB-SKILL:** Use superpowers:finishing-a-development-branch
|
|
50
|
+
- Follow that skill to verify tests, present options, execute choice
|
|
51
|
+
|
|
52
|
+
## When to Stop and Ask for Help
|
|
53
|
+
|
|
54
|
+
**STOP executing immediately when:**
|
|
55
|
+
- Hit a blocker mid-batch (missing dependency, test fails, instruction unclear)
|
|
56
|
+
- Plan has critical gaps preventing starting
|
|
57
|
+
- You don't understand an instruction
|
|
58
|
+
- Verification fails repeatedly
|
|
59
|
+
|
|
60
|
+
**Ask for clarification rather than guessing.**
|
|
61
|
+
|
|
62
|
+
## When to Revisit Earlier Steps
|
|
63
|
+
|
|
64
|
+
**Return to Review (Step 1) when:**
|
|
65
|
+
- Partner updates the plan based on your feedback
|
|
66
|
+
- Fundamental approach needs rethinking
|
|
67
|
+
|
|
68
|
+
**Don't force through blockers** - stop and ask.
|
|
69
|
+
|
|
70
|
+
## Remember
|
|
71
|
+
- Review plan critically first
|
|
72
|
+
- Follow plan steps exactly
|
|
73
|
+
- Don't skip verifications
|
|
74
|
+
- Reference skills when plan says to
|
|
75
|
+
- Between batches: just report and wait
|
|
76
|
+
- Stop when blocked, don't guess
|