devskill 2.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/README.md +123 -0
- package/README.vn.md +104 -0
- package/SKILL_GUIDE.vn.md +252 -0
- package/bin/devskill.js +11 -0
- package/meta.ts +123 -0
- package/package.json +21 -0
- package/publish.sh +50 -0
- package/scripts/cli.ts +556 -0
- package/skills/builderx_api-contexts/SKILL.md +63 -0
- package/skills/builderx_api-contexts/references/core-multi-outbox.md +57 -0
- package/skills/builderx_api-controllers/SKILL.md +49 -0
- package/skills/builderx_api-controllers/references/core-fallback.md +62 -0
- package/skills/builderx_api-schemas/SKILL.md +76 -0
- package/skills/builderx_api-schemas/references/core-schema.md +78 -0
- package/skills/builderx_spa-api/SKILL.md +67 -0
- package/skills/builderx_spa-api/references/base-api.md +97 -0
- package/skills/builderx_spa-api/references/fetch.md +70 -0
- package/skills/builderx_spa-design/SKILL.md +82 -0
- package/skills/builderx_spa-design/references/core-text-design.md +64 -0
- package/skills/builderx_spa-design/references/features-feedback-actions.md +76 -0
- package/skills/builderx_spa-design/references/features-forms.md +91 -0
- package/skills/builderx_spa-design/references/features-layout-navigation.md +121 -0
- package/skills/builderx_spa-permission/SKILL.md +38 -0
- package/skills/builderx_spa-permission/references/has-permission.md +34 -0
- package/skills/composition-patterns/AGENTS.md +946 -0
- package/skills/composition-patterns/README.md +60 -0
- package/skills/composition-patterns/SKILL.md +89 -0
- package/skills/composition-patterns/SYNC.md +5 -0
- package/skills/composition-patterns/metadata.json +11 -0
- package/skills/composition-patterns/rules/_sections.md +29 -0
- package/skills/composition-patterns/rules/_template.md +24 -0
- package/skills/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/deploy-to-vercel/Archive.zip +0 -0
- package/skills/deploy-to-vercel/SKILL.md +296 -0
- package/skills/deploy-to-vercel/SYNC.md +5 -0
- package/skills/deploy-to-vercel/resources/deploy-codex.sh +301 -0
- package/skills/deploy-to-vercel/resources/deploy.sh +301 -0
- package/skills/pinia/SKILL.md +105 -0
- package/skills/pinia/references/api-in-composables.md +139 -0
- package/skills/pinia/references/setup-stores.md +105 -0
- package/skills/pinia/references/using-in-components.md +91 -0
- package/skills/pinia-options/SKILL.md +72 -0
- package/skills/pinia-options/references/core-option-stores.md +149 -0
- package/skills/pinia-options/references/using-in-options-api.md +105 -0
- package/skills/react-best-practices/AGENTS.md +3373 -0
- package/skills/react-best-practices/README.md +123 -0
- package/skills/react-best-practices/SKILL.md +143 -0
- package/skills/react-best-practices/SYNC.md +5 -0
- package/skills/react-best-practices/metadata.json +15 -0
- package/skills/react-best-practices/rules/_sections.md +46 -0
- package/skills/react-best-practices/rules/_template.md +28 -0
- package/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/skills/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/skills/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/react-best-practices/rules/server-hoist-static-io.md +142 -0
- package/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/react-native-skills/AGENTS.md +2897 -0
- package/skills/react-native-skills/README.md +165 -0
- package/skills/react-native-skills/SKILL.md +121 -0
- package/skills/react-native-skills/SYNC.md +5 -0
- package/skills/react-native-skills/metadata.json +16 -0
- package/skills/react-native-skills/rules/_sections.md +86 -0
- package/skills/react-native-skills/rules/_template.md +28 -0
- package/skills/react-native-skills/rules/animation-derived-value.md +53 -0
- package/skills/react-native-skills/rules/animation-gesture-detector-press.md +95 -0
- package/skills/react-native-skills/rules/animation-gpu-properties.md +65 -0
- package/skills/react-native-skills/rules/design-system-compound-components.md +66 -0
- package/skills/react-native-skills/rules/fonts-config-plugin.md +71 -0
- package/skills/react-native-skills/rules/imports-design-system-folder.md +68 -0
- package/skills/react-native-skills/rules/js-hoist-intl.md +61 -0
- package/skills/react-native-skills/rules/list-performance-callbacks.md +44 -0
- package/skills/react-native-skills/rules/list-performance-function-references.md +132 -0
- package/skills/react-native-skills/rules/list-performance-images.md +53 -0
- package/skills/react-native-skills/rules/list-performance-inline-objects.md +97 -0
- package/skills/react-native-skills/rules/list-performance-item-expensive.md +94 -0
- package/skills/react-native-skills/rules/list-performance-item-memo.md +82 -0
- package/skills/react-native-skills/rules/list-performance-item-types.md +104 -0
- package/skills/react-native-skills/rules/list-performance-virtualize.md +67 -0
- package/skills/react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
- package/skills/react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
- package/skills/react-native-skills/rules/navigation-native-navigators.md +188 -0
- package/skills/react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
- package/skills/react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
- package/skills/react-native-skills/rules/react-state-dispatcher.md +91 -0
- package/skills/react-native-skills/rules/react-state-fallback.md +56 -0
- package/skills/react-native-skills/rules/react-state-minimize.md +65 -0
- package/skills/react-native-skills/rules/rendering-no-falsy-and.md +74 -0
- package/skills/react-native-skills/rules/rendering-text-in-text-component.md +36 -0
- package/skills/react-native-skills/rules/scroll-position-no-state.md +82 -0
- package/skills/react-native-skills/rules/state-ground-truth.md +80 -0
- package/skills/react-native-skills/rules/ui-expo-image.md +66 -0
- package/skills/react-native-skills/rules/ui-image-gallery.md +104 -0
- package/skills/react-native-skills/rules/ui-measure-views.md +78 -0
- package/skills/react-native-skills/rules/ui-menus.md +174 -0
- package/skills/react-native-skills/rules/ui-native-modals.md +77 -0
- package/skills/react-native-skills/rules/ui-pressable.md +61 -0
- package/skills/react-native-skills/rules/ui-safe-area-scroll.md +65 -0
- package/skills/react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
- package/skills/react-native-skills/rules/ui-styling.md +87 -0
- package/skills/slidev/LICENSE.md +21 -0
- package/skills/slidev/README.md +61 -0
- package/skills/slidev/SKILL.md +189 -0
- package/skills/slidev/SYNC.md +5 -0
- package/skills/slidev/references/animation-click-marker.md +37 -0
- package/skills/slidev/references/animation-drawing.md +68 -0
- package/skills/slidev/references/animation-rough-marker.md +53 -0
- package/skills/slidev/references/api-slide-hooks.md +37 -0
- package/skills/slidev/references/build-og-image.md +36 -0
- package/skills/slidev/references/build-pdf.md +40 -0
- package/skills/slidev/references/build-remote-assets.md +34 -0
- package/skills/slidev/references/build-seo-meta.md +43 -0
- package/skills/slidev/references/code-groups.md +64 -0
- package/skills/slidev/references/code-import-snippet.md +55 -0
- package/skills/slidev/references/code-line-highlighting.md +50 -0
- package/skills/slidev/references/code-line-numbers.md +46 -0
- package/skills/slidev/references/code-magic-move.md +57 -0
- package/skills/slidev/references/code-max-height.md +37 -0
- package/skills/slidev/references/code-twoslash.md +42 -0
- package/skills/slidev/references/core-animations.md +196 -0
- package/skills/slidev/references/core-cli.md +140 -0
- package/skills/slidev/references/core-components.md +197 -0
- package/skills/slidev/references/core-exporting.md +148 -0
- package/skills/slidev/references/core-frontmatter.md +195 -0
- package/skills/slidev/references/core-global-context.md +155 -0
- package/skills/slidev/references/core-headmatter.md +188 -0
- package/skills/slidev/references/core-hosting.md +152 -0
- package/skills/slidev/references/core-layouts.md +286 -0
- package/skills/slidev/references/core-syntax.md +155 -0
- package/skills/slidev/references/diagram-latex.md +55 -0
- package/skills/slidev/references/diagram-mermaid.md +44 -0
- package/skills/slidev/references/diagram-plantuml.md +45 -0
- package/skills/slidev/references/editor-monaco-run.md +44 -0
- package/skills/slidev/references/editor-monaco-write.md +24 -0
- package/skills/slidev/references/editor-monaco.md +50 -0
- package/skills/slidev/references/editor-prettier.md +40 -0
- package/skills/slidev/references/editor-side.md +23 -0
- package/skills/slidev/references/editor-vscode.md +55 -0
- package/skills/slidev/references/layout-canvas-size.md +25 -0
- package/skills/slidev/references/layout-draggable.md +57 -0
- package/skills/slidev/references/layout-global-layers.md +50 -0
- package/skills/slidev/references/layout-slots.md +75 -0
- package/skills/slidev/references/layout-transform.md +33 -0
- package/skills/slidev/references/layout-zoom.md +39 -0
- package/skills/slidev/references/presenter-notes-ruby.md +35 -0
- package/skills/slidev/references/presenter-recording.md +30 -0
- package/skills/slidev/references/presenter-remote.md +40 -0
- package/skills/slidev/references/presenter-timer.md +34 -0
- package/skills/slidev/references/style-direction.md +34 -0
- package/skills/slidev/references/style-icons.md +46 -0
- package/skills/slidev/references/style-scoped.md +50 -0
- package/skills/slidev/references/syntax-block-frontmatter.md +39 -0
- package/skills/slidev/references/syntax-frontmatter-merging.md +49 -0
- package/skills/slidev/references/syntax-importing-slides.md +60 -0
- package/skills/slidev/references/syntax-mdc.md +51 -0
- package/skills/slidev/references/tool-eject-theme.md +27 -0
- package/skills/tsdown/LICENSE.md +22 -0
- package/skills/tsdown/README.md +77 -0
- package/skills/tsdown/SKILL.md +407 -0
- package/skills/tsdown/SYNC.md +5 -0
- package/skills/tsdown/references/README.md +139 -0
- package/skills/tsdown/references/advanced-benchmark.md +8 -0
- package/skills/tsdown/references/advanced-ci.md +89 -0
- package/skills/tsdown/references/advanced-hooks.md +363 -0
- package/skills/tsdown/references/advanced-plugins.md +381 -0
- package/skills/tsdown/references/advanced-programmatic.md +378 -0
- package/skills/tsdown/references/advanced-rolldown-options.md +117 -0
- package/skills/tsdown/references/guide-getting-started.md +178 -0
- package/skills/tsdown/references/guide-introduction.md +42 -0
- package/skills/tsdown/references/guide-migrate-from-tsup.md +189 -0
- package/skills/tsdown/references/option-cjs-default.md +98 -0
- package/skills/tsdown/references/option-cleaning.md +275 -0
- package/skills/tsdown/references/option-config-file.md +281 -0
- package/skills/tsdown/references/option-css.md +301 -0
- package/skills/tsdown/references/option-dependencies.md +385 -0
- package/skills/tsdown/references/option-dts.md +251 -0
- package/skills/tsdown/references/option-entry.md +211 -0
- package/skills/tsdown/references/option-exe.md +120 -0
- package/skills/tsdown/references/option-lint.md +127 -0
- package/skills/tsdown/references/option-log-level.md +91 -0
- package/skills/tsdown/references/option-minification.md +177 -0
- package/skills/tsdown/references/option-output-directory.md +270 -0
- package/skills/tsdown/references/option-output-format.md +181 -0
- package/skills/tsdown/references/option-package-exports.md +320 -0
- package/skills/tsdown/references/option-platform.md +256 -0
- package/skills/tsdown/references/option-root.md +88 -0
- package/skills/tsdown/references/option-shims.md +299 -0
- package/skills/tsdown/references/option-sourcemap.md +301 -0
- package/skills/tsdown/references/option-target.md +222 -0
- package/skills/tsdown/references/option-tree-shaking.md +335 -0
- package/skills/tsdown/references/option-unbundle.md +310 -0
- package/skills/tsdown/references/option-watch-mode.md +261 -0
- package/skills/tsdown/references/recipe-react.md +338 -0
- package/skills/tsdown/references/recipe-solid.md +46 -0
- package/skills/tsdown/references/recipe-svelte.md +54 -0
- package/skills/tsdown/references/recipe-vue.md +387 -0
- package/skills/tsdown/references/recipe-wasm.md +125 -0
- package/skills/tsdown/references/reference-cli.md +472 -0
- package/skills/turborepo/LICENSE.md +7 -0
- package/skills/turborepo/SKILL.md +951 -0
- package/skills/turborepo/SYNC.md +5 -0
- package/skills/turborepo/command/turborepo.md +70 -0
- package/skills/turborepo/references/best-practices/RULE.md +241 -0
- package/skills/turborepo/references/best-practices/dependencies.md +246 -0
- package/skills/turborepo/references/best-practices/packages.md +335 -0
- package/skills/turborepo/references/best-practices/structure.md +297 -0
- package/skills/turborepo/references/boundaries/RULE.md +126 -0
- package/skills/turborepo/references/caching/RULE.md +153 -0
- package/skills/turborepo/references/caching/gotchas.md +190 -0
- package/skills/turborepo/references/caching/remote-cache.md +127 -0
- package/skills/turborepo/references/ci/RULE.md +79 -0
- package/skills/turborepo/references/ci/github-actions.md +162 -0
- package/skills/turborepo/references/ci/patterns.md +145 -0
- package/skills/turborepo/references/ci/vercel.md +103 -0
- package/skills/turborepo/references/cli/RULE.md +100 -0
- package/skills/turborepo/references/cli/commands.md +297 -0
- package/skills/turborepo/references/configuration/RULE.md +235 -0
- package/skills/turborepo/references/configuration/global-options.md +239 -0
- package/skills/turborepo/references/configuration/gotchas.md +368 -0
- package/skills/turborepo/references/configuration/tasks.md +325 -0
- package/skills/turborepo/references/environment/RULE.md +123 -0
- package/skills/turborepo/references/environment/gotchas.md +175 -0
- package/skills/turborepo/references/environment/modes.md +101 -0
- package/skills/turborepo/references/filtering/RULE.md +148 -0
- package/skills/turborepo/references/filtering/patterns.md +152 -0
- package/skills/turborepo/references/watch/RULE.md +99 -0
- package/skills/vercel-cli-with-tokens/SKILL.md +328 -0
- package/skills/vercel-cli-with-tokens/SYNC.md +5 -0
- package/skills/vue/SKILL.md +90 -0
- package/skills/vue/references/composables.md +54 -0
- package/skills/vue/references/lifecycle.md +31 -0
- package/skills/vue/references/props-emits.md +62 -0
- package/skills/vue/references/provide-inject.md +47 -0
- package/skills/vue/references/state.md +65 -0
- package/skills/vue-antdv-tailwind/SKILL.md +33 -0
- package/skills/vue-antdv-tailwind/references/styling-rules.md +61 -0
- package/skills/vue-best-practices/LICENSE.md +21 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/SYNC.md +5 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-jsx-best-practices/LICENSE.md +21 -0
- package/skills/vue-jsx-best-practices/SKILL.md +12 -0
- package/skills/vue-jsx-best-practices/SYNC.md +5 -0
- package/skills/vue-jsx-best-practices/reference/render-function-jsx-vue-vs-react.md +141 -0
- package/skills/vue-options/SKILL.md +98 -0
- package/skills/vue-options/references/lifecycle.md +107 -0
- package/skills/vue-options/references/mixins.md +96 -0
- package/skills/vue-options/references/props-emits.md +106 -0
- package/skills/vue-options/references/provide-inject.md +92 -0
- package/skills/vue-options/references/state.md +115 -0
- package/skills/vue-options-api-best-practices/LICENSE.md +21 -0
- package/skills/vue-options-api-best-practices/SKILL.md +23 -0
- package/skills/vue-options-api-best-practices/SYNC.md +5 -0
- package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-lifecycle-hooks.md +95 -0
- package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-methods.md +68 -0
- package/skills/vue-options-api-best-practices/reference/stateful-methods-lifecycle.md +61 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-arrow-functions-validators.md +141 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-computed-return-types.md +192 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-proptype-complex-types.md +212 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-provide-inject-limitations.md +135 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-type-event-handlers.md +202 -0
- package/skills/vue-options-api-best-practices/reference/ts-options-api-use-definecomponent.md +172 -0
- package/skills/vue-options-api-best-practices/reference/ts-strict-mode-options-api.md +197 -0
- package/skills/vue-pinia-best-practices/LICENSE.md +21 -0
- package/skills/vue-pinia-best-practices/SKILL.md +21 -0
- package/skills/vue-pinia-best-practices/SYNC.md +5 -0
- package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
- package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
- package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
- package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
- package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
- package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
- package/skills/vue-router-best-practices/LICENSE.md +21 -0
- package/skills/vue-router-best-practices/SKILL.md +23 -0
- package/skills/vue-router-best-practices/SYNC.md +5 -0
- package/skills/vue-router-best-practices/reference/router-beforeenter-no-param-trigger.md +167 -0
- package/skills/vue-router-best-practices/reference/router-beforerouteenter-no-this.md +176 -0
- package/skills/vue-router-best-practices/reference/router-guard-async-await-pattern.md +227 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-infinite-loop.md +187 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +150 -0
- package/skills/vue-router-best-practices/reference/router-param-change-no-lifecycle.md +181 -0
- package/skills/vue-router-best-practices/reference/router-simple-routing-cleanup.md +209 -0
- package/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +183 -0
- package/skills/vue-testing-best-practices/LICENSE.md +21 -0
- package/skills/vue-testing-best-practices/SKILL.md +29 -0
- package/skills/vue-testing-best-practices/SYNC.md +5 -0
- package/skills/vue-testing-best-practices/reference/async-component-testing.md +163 -0
- package/skills/vue-testing-best-practices/reference/teleport-testing-complexity.md +158 -0
- package/skills/vue-testing-best-practices/reference/testing-async-await-flushpromises.md +175 -0
- package/skills/vue-testing-best-practices/reference/testing-browser-vs-node-runners.md +208 -0
- package/skills/vue-testing-best-practices/reference/testing-component-blackbox-approach.md +144 -0
- package/skills/vue-testing-best-practices/reference/testing-composables-helper-wrapper.md +238 -0
- package/skills/vue-testing-best-practices/reference/testing-e2e-playwright-recommended.md +242 -0
- package/skills/vue-testing-best-practices/reference/testing-no-snapshot-only.md +197 -0
- package/skills/vue-testing-best-practices/reference/testing-pinia-store-setup.md +228 -0
- package/skills/vue-testing-best-practices/reference/testing-suspense-async-components.md +229 -0
- package/skills/vue-testing-best-practices/reference/testing-vitest-recommended-for-vue.md +204 -0
- package/skills/vueuse-functions/LICENSE.md +21 -0
- package/skills/vueuse-functions/SKILL.md +419 -0
- package/skills/vueuse-functions/SYNC.md +5 -0
- package/skills/vueuse-functions/references/computedAsync.md +195 -0
- package/skills/vueuse-functions/references/computedEager.md +62 -0
- package/skills/vueuse-functions/references/computedInject.md +137 -0
- package/skills/vueuse-functions/references/computedWithControl.md +98 -0
- package/skills/vueuse-functions/references/createEventHook.md +86 -0
- package/skills/vueuse-functions/references/createGenericProjection.md +25 -0
- package/skills/vueuse-functions/references/createGlobalState.md +95 -0
- package/skills/vueuse-functions/references/createInjectionState.md +215 -0
- package/skills/vueuse-functions/references/createProjection.md +31 -0
- package/skills/vueuse-functions/references/createRef.md +54 -0
- package/skills/vueuse-functions/references/createReusableTemplate.md +357 -0
- package/skills/vueuse-functions/references/createSharedComposable.md +42 -0
- package/skills/vueuse-functions/references/createTemplatePromise.md +306 -0
- package/skills/vueuse-functions/references/createUnrefFn.md +51 -0
- package/skills/vueuse-functions/references/extendRef.md +76 -0
- package/skills/vueuse-functions/references/from.md +80 -0
- package/skills/vueuse-functions/references/get.md +30 -0
- package/skills/vueuse-functions/references/injectLocal.md +35 -0
- package/skills/vueuse-functions/references/isDefined.md +31 -0
- package/skills/vueuse-functions/references/logicAnd.md +40 -0
- package/skills/vueuse-functions/references/logicNot.md +36 -0
- package/skills/vueuse-functions/references/logicOr.md +40 -0
- package/skills/vueuse-functions/references/makeDestructurable.md +41 -0
- package/skills/vueuse-functions/references/onClickOutside.md +221 -0
- package/skills/vueuse-functions/references/onElementRemoval.md +88 -0
- package/skills/vueuse-functions/references/onKeyStroke.md +211 -0
- package/skills/vueuse-functions/references/onLongPress.md +227 -0
- package/skills/vueuse-functions/references/onStartTyping.md +53 -0
- package/skills/vueuse-functions/references/provideLocal.md +37 -0
- package/skills/vueuse-functions/references/reactify.md +144 -0
- package/skills/vueuse-functions/references/reactifyObject.md +62 -0
- package/skills/vueuse-functions/references/reactiveComputed.md +34 -0
- package/skills/vueuse-functions/references/reactiveOmit.md +86 -0
- package/skills/vueuse-functions/references/reactivePick.md +106 -0
- package/skills/vueuse-functions/references/refAutoReset.md +46 -0
- package/skills/vueuse-functions/references/refDebounced.md +81 -0
- package/skills/vueuse-functions/references/refDefault.md +36 -0
- package/skills/vueuse-functions/references/refManualReset.md +44 -0
- package/skills/vueuse-functions/references/refThrottled.md +99 -0
- package/skills/vueuse-functions/references/refWithControl.md +146 -0
- package/skills/vueuse-functions/references/set.md +30 -0
- package/skills/vueuse-functions/references/syncRef.md +195 -0
- package/skills/vueuse-functions/references/syncRefs.md +128 -0
- package/skills/vueuse-functions/references/templateRef.md +86 -0
- package/skills/vueuse-functions/references/toObserver.md +38 -0
- package/skills/vueuse-functions/references/toReactive.md +41 -0
- package/skills/vueuse-functions/references/toRef.md +75 -0
- package/skills/vueuse-functions/references/toRefs.md +81 -0
- package/skills/vueuse-functions/references/tryOnBeforeMount.md +34 -0
- package/skills/vueuse-functions/references/tryOnBeforeUnmount.md +32 -0
- package/skills/vueuse-functions/references/tryOnMounted.md +34 -0
- package/skills/vueuse-functions/references/tryOnScopeDispose.md +31 -0
- package/skills/vueuse-functions/references/tryOnUnmounted.md +32 -0
- package/skills/vueuse-functions/references/unrefElement.md +54 -0
- package/skills/vueuse-functions/references/until.md +161 -0
- package/skills/vueuse-functions/references/useAbs.md +31 -0
- package/skills/vueuse-functions/references/useActiveElement.md +85 -0
- package/skills/vueuse-functions/references/useAnimate.md +181 -0
- package/skills/vueuse-functions/references/useArrayDifference.md +84 -0
- package/skills/vueuse-functions/references/useArrayEvery.md +59 -0
- package/skills/vueuse-functions/references/useArrayFilter.md +63 -0
- package/skills/vueuse-functions/references/useArrayFind.md +50 -0
- package/skills/vueuse-functions/references/useArrayFindIndex.md +59 -0
- package/skills/vueuse-functions/references/useArrayFindLast.md +52 -0
- package/skills/vueuse-functions/references/useArrayIncludes.md +63 -0
- package/skills/vueuse-functions/references/useArrayJoin.md +74 -0
- package/skills/vueuse-functions/references/useArrayMap.md +59 -0
- package/skills/vueuse-functions/references/useArrayReduce.md +81 -0
- package/skills/vueuse-functions/references/useArraySome.md +59 -0
- package/skills/vueuse-functions/references/useArrayUnique.md +76 -0
- package/skills/vueuse-functions/references/useAsyncQueue.md +136 -0
- package/skills/vueuse-functions/references/useAsyncState.md +185 -0
- package/skills/vueuse-functions/references/useAsyncValidator.md +70 -0
- package/skills/vueuse-functions/references/useAuth.md +123 -0
- package/skills/vueuse-functions/references/useAverage.md +36 -0
- package/skills/vueuse-functions/references/useAxios.md +325 -0
- package/skills/vueuse-functions/references/useBase64.md +136 -0
- package/skills/vueuse-functions/references/useBattery.md +78 -0
- package/skills/vueuse-functions/references/useBluetooth.md +175 -0
- package/skills/vueuse-functions/references/useBreakpoints.md +172 -0
- package/skills/vueuse-functions/references/useBroadcastChannel.md +74 -0
- package/skills/vueuse-functions/references/useBrowserLocation.md +83 -0
- package/skills/vueuse-functions/references/useCached.md +52 -0
- package/skills/vueuse-functions/references/useCeil.md +31 -0
- package/skills/vueuse-functions/references/useChangeCase.md +79 -0
- package/skills/vueuse-functions/references/useClamp.md +85 -0
- package/skills/vueuse-functions/references/useClipboard.md +123 -0
- package/skills/vueuse-functions/references/useClipboardItems.md +94 -0
- package/skills/vueuse-functions/references/useCloned.md +91 -0
- package/skills/vueuse-functions/references/useColorMode.md +172 -0
- package/skills/vueuse-functions/references/useConfirmDialog.md +159 -0
- package/skills/vueuse-functions/references/useCookies.md +162 -0
- package/skills/vueuse-functions/references/useCountdown.md +105 -0
- package/skills/vueuse-functions/references/useCounter.md +86 -0
- package/skills/vueuse-functions/references/useCssSupports.md +35 -0
- package/skills/vueuse-functions/references/useCssVar.md +50 -0
- package/skills/vueuse-functions/references/useCurrentElement.md +61 -0
- package/skills/vueuse-functions/references/useCycleList.md +75 -0
- package/skills/vueuse-functions/references/useDark.md +144 -0
- package/skills/vueuse-functions/references/useDateFormat.md +145 -0
- package/skills/vueuse-functions/references/useDebounceFn.md +100 -0
- package/skills/vueuse-functions/references/useDebouncedRefHistory.md +40 -0
- package/skills/vueuse-functions/references/useDeviceMotion.md +86 -0
- package/skills/vueuse-functions/references/useDeviceOrientation.md +62 -0
- package/skills/vueuse-functions/references/useDevicePixelRatio.md +44 -0
- package/skills/vueuse-functions/references/useDevicesList.md +90 -0
- package/skills/vueuse-functions/references/useDisplayMedia.md +71 -0
- package/skills/vueuse-functions/references/useDocumentVisibility.md +45 -0
- package/skills/vueuse-functions/references/useDraggable.md +317 -0
- package/skills/vueuse-functions/references/useDrauu.md +65 -0
- package/skills/vueuse-functions/references/useDropZone.md +83 -0
- package/skills/vueuse-functions/references/useElementBounding.md +131 -0
- package/skills/vueuse-functions/references/useElementByPoint.md +48 -0
- package/skills/vueuse-functions/references/useElementHover.md +79 -0
- package/skills/vueuse-functions/references/useElementSize.md +78 -0
- package/skills/vueuse-functions/references/useElementVisibility.md +123 -0
- package/skills/vueuse-functions/references/useEventBus.md +101 -0
- package/skills/vueuse-functions/references/useEventListener.md +226 -0
- package/skills/vueuse-functions/references/useEventSource.md +204 -0
- package/skills/vueuse-functions/references/useExtractedObservable.md +198 -0
- package/skills/vueuse-functions/references/useEyeDropper.md +71 -0
- package/skills/vueuse-functions/references/useFavicon.md +67 -0
- package/skills/vueuse-functions/references/useFetch.md +546 -0
- package/skills/vueuse-functions/references/useFileDialog.md +91 -0
- package/skills/vueuse-functions/references/useFileSystemAccess.md +162 -0
- package/skills/vueuse-functions/references/useFirestore.md +129 -0
- package/skills/vueuse-functions/references/useFloor.md +31 -0
- package/skills/vueuse-functions/references/useFocus.md +99 -0
- package/skills/vueuse-functions/references/useFocusTrap.md +245 -0
- package/skills/vueuse-functions/references/useFocusWithin.md +57 -0
- package/skills/vueuse-functions/references/useFps.md +28 -0
- package/skills/vueuse-functions/references/useFullscreen.md +75 -0
- package/skills/vueuse-functions/references/useFuse.md +107 -0
- package/skills/vueuse-functions/references/useGamepad.md +222 -0
- package/skills/vueuse-functions/references/useGeolocation.md +85 -0
- package/skills/vueuse-functions/references/useIDBKeyval.md +93 -0
- package/skills/vueuse-functions/references/useIdle.md +88 -0
- package/skills/vueuse-functions/references/useImage.md +86 -0
- package/skills/vueuse-functions/references/useInfiniteScroll.md +157 -0
- package/skills/vueuse-functions/references/useIntersectionObserver.md +118 -0
- package/skills/vueuse-functions/references/useInterval.md +112 -0
- package/skills/vueuse-functions/references/useIntervalFn.md +50 -0
- package/skills/vueuse-functions/references/useIpcRenderer.md +144 -0
- package/skills/vueuse-functions/references/useIpcRendererInvoke.md +58 -0
- package/skills/vueuse-functions/references/useIpcRendererOn.md +52 -0
- package/skills/vueuse-functions/references/useJwt.md +57 -0
- package/skills/vueuse-functions/references/useKeyModifier.md +87 -0
- package/skills/vueuse-functions/references/useLastChanged.md +63 -0
- package/skills/vueuse-functions/references/useLocalStorage.md +41 -0
- package/skills/vueuse-functions/references/useMagicKeys.md +245 -0
- package/skills/vueuse-functions/references/useManualRefHistory.md +204 -0
- package/skills/vueuse-functions/references/useMath.md +47 -0
- package/skills/vueuse-functions/references/useMax.md +36 -0
- package/skills/vueuse-functions/references/useMediaControls.md +571 -0
- package/skills/vueuse-functions/references/useMediaQuery.md +53 -0
- package/skills/vueuse-functions/references/useMemoize.md +175 -0
- package/skills/vueuse-functions/references/useMemory.md +71 -0
- package/skills/vueuse-functions/references/useMin.md +36 -0
- package/skills/vueuse-functions/references/useMounted.md +38 -0
- package/skills/vueuse-functions/references/useMouse.md +113 -0
- package/skills/vueuse-functions/references/useMouseInElement.md +123 -0
- package/skills/vueuse-functions/references/useMousePressed.md +112 -0
- package/skills/vueuse-functions/references/useMutationObserver.md +61 -0
- package/skills/vueuse-functions/references/useNProgress.md +78 -0
- package/skills/vueuse-functions/references/useNavigatorLanguage.md +57 -0
- package/skills/vueuse-functions/references/useNetwork.md +106 -0
- package/skills/vueuse-functions/references/useNow.md +79 -0
- package/skills/vueuse-functions/references/useObjectUrl.md +55 -0
- package/skills/vueuse-functions/references/useObservable.md +91 -0
- package/skills/vueuse-functions/references/useOffsetPagination.md +199 -0
- package/skills/vueuse-functions/references/useOnline.md +41 -0
- package/skills/vueuse-functions/references/usePageLeave.md +42 -0
- package/skills/vueuse-functions/references/useParallax.md +58 -0
- package/skills/vueuse-functions/references/useParentElement.md +54 -0
- package/skills/vueuse-functions/references/usePerformanceObserver.md +48 -0
- package/skills/vueuse-functions/references/usePermission.md +79 -0
- package/skills/vueuse-functions/references/usePointer.md +89 -0
- package/skills/vueuse-functions/references/usePointerLock.md +60 -0
- package/skills/vueuse-functions/references/usePointerSwipe.md +80 -0
- package/skills/vueuse-functions/references/usePrecision.md +49 -0
- package/skills/vueuse-functions/references/usePreferredColorScheme.md +42 -0
- package/skills/vueuse-functions/references/usePreferredContrast.md +42 -0
- package/skills/vueuse-functions/references/usePreferredDark.md +41 -0
- package/skills/vueuse-functions/references/usePreferredLanguages.md +41 -0
- package/skills/vueuse-functions/references/usePreferredReducedMotion.md +42 -0
- package/skills/vueuse-functions/references/usePreferredReducedTransparency.md +42 -0
- package/skills/vueuse-functions/references/usePrevious.md +40 -0
- package/skills/vueuse-functions/references/useProjection.md +38 -0
- package/skills/vueuse-functions/references/useQRCode.md +53 -0
- package/skills/vueuse-functions/references/useRTDB.md +83 -0
- package/skills/vueuse-functions/references/useRafFn.md +68 -0
- package/skills/vueuse-functions/references/useRefHistory.md +285 -0
- package/skills/vueuse-functions/references/useResizeObserver.md +109 -0
- package/skills/vueuse-functions/references/useRound.md +31 -0
- package/skills/vueuse-functions/references/useRouteHash.md +27 -0
- package/skills/vueuse-functions/references/useRouteParams.md +38 -0
- package/skills/vueuse-functions/references/useRouteQuery.md +79 -0
- package/skills/vueuse-functions/references/useSSRWidth.md +47 -0
- package/skills/vueuse-functions/references/useScreenOrientation.md +96 -0
- package/skills/vueuse-functions/references/useScreenSafeArea.md +60 -0
- package/skills/vueuse-functions/references/useScriptTag.md +116 -0
- package/skills/vueuse-functions/references/useScroll.md +238 -0
- package/skills/vueuse-functions/references/useScrollLock.md +66 -0
- package/skills/vueuse-functions/references/useSessionStorage.md +41 -0
- package/skills/vueuse-functions/references/useShare.md +68 -0
- package/skills/vueuse-functions/references/useSortable.md +235 -0
- package/skills/vueuse-functions/references/useSorted.md +90 -0
- package/skills/vueuse-functions/references/useSpeechRecognition.md +94 -0
- package/skills/vueuse-functions/references/useSpeechSynthesis.md +105 -0
- package/skills/vueuse-functions/references/useStepper.md +137 -0
- package/skills/vueuse-functions/references/useStorage.md +278 -0
- package/skills/vueuse-functions/references/useStorageAsync.md +136 -0
- package/skills/vueuse-functions/references/useStyleTag.md +131 -0
- package/skills/vueuse-functions/references/useSubject.md +77 -0
- package/skills/vueuse-functions/references/useSubscription.md +33 -0
- package/skills/vueuse-functions/references/useSum.md +36 -0
- package/skills/vueuse-functions/references/useSupported.md +29 -0
- package/skills/vueuse-functions/references/useSwipe.md +75 -0
- package/skills/vueuse-functions/references/useTemplateRefsList.md +37 -0
- package/skills/vueuse-functions/references/useTextDirection.md +75 -0
- package/skills/vueuse-functions/references/useTextSelection.md +40 -0
- package/skills/vueuse-functions/references/useTextareaAutosize.md +97 -0
- package/skills/vueuse-functions/references/useThrottleFn.md +57 -0
- package/skills/vueuse-functions/references/useThrottledRefHistory.md +47 -0
- package/skills/vueuse-functions/references/useTimeAgo.md +154 -0
- package/skills/vueuse-functions/references/useTimeAgoIntl.md +117 -0
- package/skills/vueuse-functions/references/useTimeout.md +113 -0
- package/skills/vueuse-functions/references/useTimeoutFn.md +51 -0
- package/skills/vueuse-functions/references/useTimeoutPoll.md +47 -0
- package/skills/vueuse-functions/references/useTimestamp.md +89 -0
- package/skills/vueuse-functions/references/useTitle.md +113 -0
- package/skills/vueuse-functions/references/useToNumber.md +54 -0
- package/skills/vueuse-functions/references/useToString.md +34 -0
- package/skills/vueuse-functions/references/useToggle.md +103 -0
- package/skills/vueuse-functions/references/useTransition.md +265 -0
- package/skills/vueuse-functions/references/useTrunc.md +33 -0
- package/skills/vueuse-functions/references/useUrlSearchParams.md +121 -0
- package/skills/vueuse-functions/references/useUserMedia.md +1138 -0
- package/skills/vueuse-functions/references/useVModel.md +182 -0
- package/skills/vueuse-functions/references/useVModels.md +67 -0
- package/skills/vueuse-functions/references/useVibrate.md +87 -0
- package/skills/vueuse-functions/references/useVirtualList.md +182 -0
- package/skills/vueuse-functions/references/useWakeLock.md +50 -0
- package/skills/vueuse-functions/references/useWebNotification.md +176 -0
- package/skills/vueuse-functions/references/useWebSocket.md +299 -0
- package/skills/vueuse-functions/references/useWebWorker.md +60 -0
- package/skills/vueuse-functions/references/useWebWorkerFn.md +102 -0
- package/skills/vueuse-functions/references/useWindowFocus.md +46 -0
- package/skills/vueuse-functions/references/useWindowScroll.md +61 -0
- package/skills/vueuse-functions/references/useWindowSize.md +76 -0
- package/skills/vueuse-functions/references/useZoomFactor.md +53 -0
- package/skills/vueuse-functions/references/useZoomLevel.md +53 -0
- package/skills/vueuse-functions/references/watchArray.md +53 -0
- package/skills/vueuse-functions/references/watchAtMost.md +55 -0
- package/skills/vueuse-functions/references/watchDebounced.md +101 -0
- package/skills/vueuse-functions/references/watchDeep.md +54 -0
- package/skills/vueuse-functions/references/watchExtractedObservable.md +192 -0
- package/skills/vueuse-functions/references/watchIgnorable.md +120 -0
- package/skills/vueuse-functions/references/watchImmediate.md +44 -0
- package/skills/vueuse-functions/references/watchOnce.md +41 -0
- package/skills/vueuse-functions/references/watchPausable.md +86 -0
- package/skills/vueuse-functions/references/watchThrottled.md +108 -0
- package/skills/vueuse-functions/references/watchTriggerable.md +98 -0
- package/skills/vueuse-functions/references/watchWithFilter.md +54 -0
- package/skills/vueuse-functions/references/whenever.md +100 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/skills/web-design-guidelines/SYNC.md +5 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: builderx_api-controllers
|
|
3
|
+
description: Guide to Phoenix Controller structure in builderx_api using FallbackController and standard tuple responses.
|
|
4
|
+
metadata:
|
|
5
|
+
author: AI Assistant
|
|
6
|
+
version: "2026.03.23"
|
|
7
|
+
source: Source code builderx_api
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# BuilderX API Controllers
|
|
11
|
+
|
|
12
|
+
> Conventions for handling HTTP requests and responses at the Web API layer.
|
|
13
|
+
|
|
14
|
+
## Core
|
|
15
|
+
|
|
16
|
+
| Topic | Description | Reference |
|
|
17
|
+
|-------|-------------|-----------|
|
|
18
|
+
| FallbackController | Centralized response handling via tuples | [core-fallback](references/core-fallback.md) |
|
|
19
|
+
| Tuple Returns | Standard formats like `{:success, ...}` or `{:failed, ...}` | [core-fallback](references/core-fallback.md) |
|
|
20
|
+
|
|
21
|
+
## Quick Reference
|
|
22
|
+
|
|
23
|
+
```elixir
|
|
24
|
+
defmodule BuilderxApiWeb.V1.ExampleController do
|
|
25
|
+
use BuilderxApiWeb, :controller
|
|
26
|
+
|
|
27
|
+
# Required: Declare action_fallback
|
|
28
|
+
action_fallback BuilderxApiWeb.FallbackController
|
|
29
|
+
|
|
30
|
+
def show(conn, %{"id" => id}) do
|
|
31
|
+
# Context functions should return tuples compatible with FallbackController instead of standard {:ok, data}
|
|
32
|
+
# Example:
|
|
33
|
+
{:success, :with_data, %{id: id, name: "Sample"}}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def delete(conn, _params) do
|
|
37
|
+
# Return success without data
|
|
38
|
+
{:success, :success_only}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create(conn, _params) do
|
|
42
|
+
# Return failure with a custom reason
|
|
43
|
+
{:failed, :with_reason, "Invalid input data"}
|
|
44
|
+
|
|
45
|
+
# Or return an error from a Changeset validation failure
|
|
46
|
+
# {:error, changeset}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core-fallback
|
|
3
|
+
description: Standard usage of Action Fallback in Phoenix Controllers of builderx_api.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Action Fallback in Controllers
|
|
7
|
+
|
|
8
|
+
Controllers usually do not handle rendering JSON directly. They delegate this responsibility to `BuilderxApiWeb.FallbackController`.
|
|
9
|
+
|
|
10
|
+
## Mandatory Pattern
|
|
11
|
+
|
|
12
|
+
Always include the following line at the top of every API controller:
|
|
13
|
+
|
|
14
|
+
```elixir
|
|
15
|
+
action_fallback BuilderxApiWeb.FallbackController
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Valid Tuple Responses
|
|
19
|
+
|
|
20
|
+
Every action in an API controller must return one of the following tuples:
|
|
21
|
+
|
|
22
|
+
1. **Success with data:**
|
|
23
|
+
```elixir
|
|
24
|
+
{:success, :with_data, data}
|
|
25
|
+
# Fallback returns JSON: %{success: true, data: data, fallback: "with_data"}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. **Success with data wrapped in a custom key:**
|
|
29
|
+
```elixir
|
|
30
|
+
{:success, :with_data, :user_info, data}
|
|
31
|
+
# Fallback returns JSON: %{success: true, fallback: "with_data", user_info: data}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
3. **Success without data (only a 200 OK status):**
|
|
35
|
+
```elixir
|
|
36
|
+
{:success, :success_only}
|
|
37
|
+
# Fallback returns JSON: %{success: true, success_only: true}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
4. **Failure with a reason:**
|
|
41
|
+
```elixir
|
|
42
|
+
{:failed, :with_reason, "Error description"}
|
|
43
|
+
# Fallback returns JSON (HTTP 422): %{success: false, reason: "Error description", fallback: "with_reason"}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
5. **Failure with an error code:**
|
|
47
|
+
```elixir
|
|
48
|
+
{:failed, :with_code, "ERR_7009"}
|
|
49
|
+
# Fallback returns JSON (HTTP 422): %{success: false, code: "ERR_7009", fallback: "with_code"}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
6. **Form / Ecto Validation Error:**
|
|
53
|
+
```elixir
|
|
54
|
+
{:error, changeset}
|
|
55
|
+
# Fallback will use ChangesetView to output the corresponding error array (HTTP 422).
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
7. **Bad Request Error:**
|
|
59
|
+
```elixir
|
|
60
|
+
{:bad_request, :with_reason, "Missing required parameters"}
|
|
61
|
+
# Fallback returns JSON (HTTP 400).
|
|
62
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: builderx_api-schemas
|
|
3
|
+
description: Guidelines for creating Ecto Schemas in builderx_api, including composite primary keys, custom json function and Ecto.Changeset.
|
|
4
|
+
metadata:
|
|
5
|
+
author: AI Assistant
|
|
6
|
+
version: "2026.03.23"
|
|
7
|
+
source: Source code builderx_api
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# BuilderX API Schemas
|
|
11
|
+
|
|
12
|
+
> Conventions and structures for defining Ecto Schemas in the builderx_api project.
|
|
13
|
+
|
|
14
|
+
## Core
|
|
15
|
+
|
|
16
|
+
| Topic | Description | Reference |
|
|
17
|
+
|-------|-------------|-----------|
|
|
18
|
+
| Schema Definition | Primary keys, site_id attribute, timestamps | [core-schema](references/core-schema.md) |
|
|
19
|
+
| JSON Serialization | Custom `json/1` and `json/2` implementation in Ecto Schema | [core-schema](references/core-schema.md) |
|
|
20
|
+
|
|
21
|
+
## Quick Reference
|
|
22
|
+
|
|
23
|
+
```elixir
|
|
24
|
+
defmodule BuilderxApi.Products.Product do
|
|
25
|
+
use Ecto.Schema
|
|
26
|
+
import Ecto.Changeset
|
|
27
|
+
|
|
28
|
+
alias BuilderxApi.Sites.Site
|
|
29
|
+
|
|
30
|
+
@primary_key {:id, :binary_id, autogenerate: true}
|
|
31
|
+
@foreign_key_type :binary_id
|
|
32
|
+
@non_required_fields [:id, :inserted_at, :updated_at]
|
|
33
|
+
|
|
34
|
+
schema "products" do
|
|
35
|
+
belongs_to(:site, Site, type: Ecto.UUID, primary_key: true)
|
|
36
|
+
|
|
37
|
+
field :name, :string
|
|
38
|
+
|
|
39
|
+
timestamps(type: :utc_datetime_usec)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def changeset(%__MODULE__{} = product, attrs \\ %{}) do
|
|
43
|
+
fields = __schema__(:fields) -- @non_required_fields
|
|
44
|
+
|
|
45
|
+
product
|
|
46
|
+
|> cast(attrs, fields)
|
|
47
|
+
|> validate_required([:site_id, :name])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Custom serializer instead of using Phoenix Views
|
|
51
|
+
def json(%__MODULE__{} = product) do
|
|
52
|
+
fields = __schema__(:fields)
|
|
53
|
+
data = Map.take(product, fields)
|
|
54
|
+
|
|
55
|
+
data =
|
|
56
|
+
case Map.fetch(product, :site) do
|
|
57
|
+
{:ok, %Ecto.Association.NotLoaded{}} ->
|
|
58
|
+
data
|
|
59
|
+
|
|
60
|
+
{:ok, value} ->
|
|
61
|
+
Map.put(data, :site, Site.json(value))
|
|
62
|
+
|
|
63
|
+
_ ->
|
|
64
|
+
data
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
data
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def json(products) when is_list(products) do
|
|
71
|
+
Enum.map(products, &json(&1))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def json(_), do: nil
|
|
75
|
+
end
|
|
76
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core-schema
|
|
3
|
+
description: Mandatory configurations when creating Ecto Schemas in builderx_api.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Core Schema
|
|
7
|
+
|
|
8
|
+
Standard conventions for declaring a Schema in builderx_api.
|
|
9
|
+
|
|
10
|
+
## 1. Composite Primary Key
|
|
11
|
+
|
|
12
|
+
In `builderx_api`, most tables use a composite primary key consisting of `id` and `site_id`. This helps isolate data by site (sharding).
|
|
13
|
+
|
|
14
|
+
```elixir
|
|
15
|
+
@primary_key {:id, :binary_id, autogenerate: true}
|
|
16
|
+
|
|
17
|
+
schema "table_name" do
|
|
18
|
+
belongs_to(:site, Site, type: Ecto.UUID, primary_key: true)
|
|
19
|
+
# ... other columns
|
|
20
|
+
end
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 2. Timestamps
|
|
24
|
+
|
|
25
|
+
Use the timestamp type with microseconds precision (`utc_datetime_usec`):
|
|
26
|
+
|
|
27
|
+
```elixir
|
|
28
|
+
timestamps(type: :utc_datetime_usec)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 3. JSON Serialization
|
|
32
|
+
|
|
33
|
+
The project **does not use** Phoenix's `views` directory to render JSON API responses for entities. Instead, each Ecto Schema implements its own `json/1` or `json/2` function to serialize the Ecto struct into a map.
|
|
34
|
+
|
|
35
|
+
```elixir
|
|
36
|
+
def json(%__MODULE__{} = product) do
|
|
37
|
+
# Get all declared schema fields
|
|
38
|
+
fields = __schema__(:fields)
|
|
39
|
+
data = Map.take(product, fields)
|
|
40
|
+
|
|
41
|
+
# Serialize associations safely if they are loaded
|
|
42
|
+
data =
|
|
43
|
+
case Map.fetch(product, :categories) do
|
|
44
|
+
{:ok, %Ecto.Association.NotLoaded{}} ->
|
|
45
|
+
data
|
|
46
|
+
|
|
47
|
+
{:ok, value} ->
|
|
48
|
+
Map.put(data, :categories, Category.json(value))
|
|
49
|
+
|
|
50
|
+
_ ->
|
|
51
|
+
data
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
data
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def json(products) when is_list(products) do
|
|
58
|
+
Enum.map(products, &json(&1))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def json(_), do: nil
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 4. Changeset and Cast Fields
|
|
65
|
+
|
|
66
|
+
To avoid listing all fields manually when calling `cast/3` in the `changeset`, the project defines a module attribute `@non_required_fields` and subtracts these fields from `__schema__(:fields)`.
|
|
67
|
+
|
|
68
|
+
```elixir
|
|
69
|
+
@non_required_fields [:id, :inserted_at, :updated_at]
|
|
70
|
+
|
|
71
|
+
def changeset(%__MODULE__{} = model, attrs \\ %{}) do
|
|
72
|
+
fields = __schema__(:fields) -- @non_required_fields
|
|
73
|
+
|
|
74
|
+
model
|
|
75
|
+
|> cast(attrs, fields)
|
|
76
|
+
|> validate_required([:site_id, :name]) # Validate required fields
|
|
77
|
+
end
|
|
78
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: builderx_spa-api
|
|
3
|
+
description: Standardized API fetching for BuilderX SPA using useApiget, useApipost, useApiDelete, and useApiProgress from @/composable/fetch. Covers GET/POST requests, file uploads, and progress tracking. Use this skill when making network requests in the builderx_spa project.
|
|
4
|
+
metadata:
|
|
5
|
+
author: Vũ Lưu
|
|
6
|
+
version: "2026.3.23"
|
|
7
|
+
source: Hand-written based on builderx_spa source code
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# BuilderX SPA API Wrapper
|
|
11
|
+
|
|
12
|
+
> Always use the built-in HTTP composables instead of using `axios` directly.
|
|
13
|
+
|
|
14
|
+
## Core
|
|
15
|
+
|
|
16
|
+
| Topic | Description | Reference |
|
|
17
|
+
|-------|-------------|-----------|
|
|
18
|
+
| Fetching Data | `useApiget`, `useApipost`, `useApiDelete`, `useApiProgress` | [fetch](references/fetch.md) |
|
|
19
|
+
| Class-based API | `BaseApi` class, extending REST controllers in `@/api` | [base-api](references/base-api.md) |
|
|
20
|
+
|
|
21
|
+
## Quick Reference
|
|
22
|
+
|
|
23
|
+
### 1. The Class-based API approach (Preferred for CRUD)
|
|
24
|
+
Used when interacting with standard REST resources. Classes exist inside `src/api/` (Core API) and `src/api/landing/` (Landing Page API).
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import productApi from '@/api/productApi'
|
|
28
|
+
import landingPageApi from '@/api/landing/pageApi'
|
|
29
|
+
|
|
30
|
+
// List resources (calls base implementation)
|
|
31
|
+
const res = await productApi.list({ site_id: 123, limit: 10 })
|
|
32
|
+
const landingRes = await landingPageApi.list({ limit: 10 })
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// Call custom endpoints defined in the child class
|
|
36
|
+
const customRes = await productApi.getProductsBuild({ search: 'shirt' })
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. The Composable approach (For one-off requests)
|
|
40
|
+
```javascript
|
|
41
|
+
import { useApiget, useApipost } from '@/composable/fetch'
|
|
42
|
+
|
|
43
|
+
export default {
|
|
44
|
+
methods: {
|
|
45
|
+
async fetchUsers() {
|
|
46
|
+
const url = `${import.meta.env.VITE_BUILDERX_API_URL}/api/v1/users`
|
|
47
|
+
// Returns a resolved axios response. Data is usually inside res.data.data
|
|
48
|
+
const res = await useApiget(url, { page: 1 })
|
|
49
|
+
console.log(res.data.data)
|
|
50
|
+
},
|
|
51
|
+
async saveProfile(payload) {
|
|
52
|
+
const url = `${import.meta.env.VITE_BUILDERX_API_URL}/api/v1/update_account`
|
|
53
|
+
// Signature: url, params (query string), body
|
|
54
|
+
await useApipost(url, null, payload)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### File Uploads (No Progress Bar)
|
|
61
|
+
```javascript
|
|
62
|
+
const formData = new FormData()
|
|
63
|
+
formData.append('file', fileObject)
|
|
64
|
+
|
|
65
|
+
// Provide headers as the 4th argument
|
|
66
|
+
await useApipost(url, null, formData, { 'Content-Type': 'multipart/form-data' })
|
|
67
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Class-based API (`@/api/baseApi.js`)
|
|
2
|
+
|
|
3
|
+
In `builderx_spa`, while `useApiget` and `useApipost` are convenient, the core CRUD operations and structured resources have dedicated service classes located in the `src/api/` folder.
|
|
4
|
+
|
|
5
|
+
These classes inherit from `BaseApi`, which automatically manages object URLs, `site_id`, `dashboard` prefixes, and standard REST HTTP calls using a customized `axiosClient`.
|
|
6
|
+
|
|
7
|
+
## 1. Creating an API Service
|
|
8
|
+
|
|
9
|
+
When creating a new API service for a resource, extend `BaseApi`. Set the `controller` name to match the backend resource.
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
// src/api/customerApi.js
|
|
13
|
+
import { BaseApi } from "./baseApi"
|
|
14
|
+
|
|
15
|
+
class CustomerApi extends BaseApi {
|
|
16
|
+
constructor() {
|
|
17
|
+
super({
|
|
18
|
+
controller: 'customer',
|
|
19
|
+
v1: true, // Adds /api/v1/ suffix
|
|
20
|
+
dashboard: false // If true, adds /dashboard/ suffix
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// You can define custom endpoints bypassing or extending getUrl()
|
|
25
|
+
getCustomReport(params = {}) {
|
|
26
|
+
// getUrl options: not_controller, is_dashboard, path
|
|
27
|
+
const url = this.getUrl(params, { path: '/custom_report' })
|
|
28
|
+
return this.axios.get(url, { params })
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Always export a singleton instance
|
|
33
|
+
export default new CustomerApi()
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 2. Dynamic URL Generation
|
|
37
|
+
|
|
38
|
+
The `getUrl(params)` function inside `BaseApi` automatically analyzes the `params` you pass to construct proper hierarchical URLs:
|
|
39
|
+
|
|
40
|
+
- If `params.site_id` exists: Injects `/site/:site_id`
|
|
41
|
+
- If `params.page_id` exists: Injects `/:page_id`
|
|
42
|
+
- Appends `/:controller` automatically (unless `not_controller: true` is passed).
|
|
43
|
+
|
|
44
|
+
## 3. Standard CRUD Methods
|
|
45
|
+
|
|
46
|
+
`BaseApi` comes with 5 out-of-the-box methods:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import customerApi from '@/api/customerApi'
|
|
50
|
+
|
|
51
|
+
// 1. list(params) => GET /api/v1[/site/:id]/customer?search=hello
|
|
52
|
+
await customerApi.list({ site_id: 1, search: 'hello' })
|
|
53
|
+
|
|
54
|
+
// 2. getById(params) => GET /api/v1[/site/:id]/customer/:id
|
|
55
|
+
await customerApi.getById({ id: 123, site_id: 1 })
|
|
56
|
+
|
|
57
|
+
// 3. create(data) => POST /api/v1[/site/:id]/customer
|
|
58
|
+
await customerApi.create({ site_id: 1, name: 'John Doe' })
|
|
59
|
+
|
|
60
|
+
// 4. update(data) => PATCH /api/v1[/site/:id]/customer/:id
|
|
61
|
+
await customerApi.update({ id: 123, site_id: 1, name: 'Jane Doe' })
|
|
62
|
+
|
|
63
|
+
// 5. delete(params) => DELETE /api/v1[/site/:id]/customer/:id
|
|
64
|
+
await customerApi.delete({ id: 123, site_id: 1 })
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> **Note:** Just like `useApiget`, all `BaseApi` methods return a Promise resolving to a mapped response: `{ success: true, status: 200, data: {...} }`. The `data` property holds the body payload.
|
|
68
|
+
|
|
69
|
+
## 4. Landing Page API Variant (`@/api/landing/baseApi.js`)
|
|
70
|
+
|
|
71
|
+
For the Landing Page module, there is a separate instance of `BaseApi` located inside `src/api/landing/`.
|
|
72
|
+
|
|
73
|
+
While it shares the same CRUD function names (`list`, `create`, etc.), it operates differently under the hood using `axiosLanding.js`:
|
|
74
|
+
|
|
75
|
+
1. **Different Base URL**: Uses `import.meta.env.VITE_LANDING_PAGE_API_URL`
|
|
76
|
+
2. **Different Cookies/Auth**:
|
|
77
|
+
- Token: `ljwt` instead of `jwt`
|
|
78
|
+
- Session ID: `lwsid` instead of `wsid`
|
|
79
|
+
- Extra Headers: `x-team-id` (from `teamset`), `x-org-id` (from `orgset`)
|
|
80
|
+
3. **Simpler URL Routing**: Its `getUrl()` method does NOT attempt to inject `/site/:site_id` or `/dashboard`. It simply appends the `controller` path to its `prefix` (default: `/api/v1/`).
|
|
81
|
+
4. **Subscription Interceptor**: Automatically catches `error_code == 3001` and triggers the `useLandingCheckStore`'s `setRequireSubscription(true)` to prompt the user to upgrade.
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// Example: src/api/landing/folderApi.js
|
|
85
|
+
import BaseApi from "./baseApi"
|
|
86
|
+
|
|
87
|
+
class FolderApi extends BaseApi {
|
|
88
|
+
constructor() {
|
|
89
|
+
super({
|
|
90
|
+
controller: 'folder'
|
|
91
|
+
// default prefix is '/api/v1/'
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export default new FolderApi()
|
|
97
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# API Fetching (`@/composable/fetch`)
|
|
2
|
+
|
|
3
|
+
BuilderX SPA wraps `axios` calls to automatically attach the JWT token (`Authorization: Bearer <jwt>`) and the session ID (`x-session-id`). It also uses an in-flight pool mechanism (`flightPool`) to prevent duplicate concurrent requests.
|
|
4
|
+
|
|
5
|
+
## Text / JSON Data
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import { useApiget, useApipost, useApiDelete } from '@/composable/fetch'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### 1. `useApiget(url, params = null, headers = {})`
|
|
12
|
+
|
|
13
|
+
Used for `GET` requests.
|
|
14
|
+
- `url`: Full endpoint URL (usually prefixed with `import.meta.env.VITE_BUILDERX_API_URL`).
|
|
15
|
+
- `params`: Object converted to query parameters in the URL (`?key=value`).
|
|
16
|
+
|
|
17
|
+
### 2. `useApipost(url, params, body, headers = {})`
|
|
18
|
+
|
|
19
|
+
Used for `POST` requests.
|
|
20
|
+
- `params`: Query parameters (pass `null` if none).
|
|
21
|
+
- `body`: The JSON payload sent in the request body.
|
|
22
|
+
|
|
23
|
+
### 3. `useApiDelete(url, params, body, headers = {})`
|
|
24
|
+
|
|
25
|
+
Used for `DELETE` requests. Notice that it accepts a `body` just like `useApipost`.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## File Uploads & Progress Tracking
|
|
30
|
+
|
|
31
|
+
### 1. Standard Upload (No Progress Tracking)
|
|
32
|
+
|
|
33
|
+
You can use `useApipost` to upload `FormData`. Just make sure to pass `null` for `params` and override the content type headers.
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
const formData = new FormData()
|
|
37
|
+
formData.append('file', this.selectedFile)
|
|
38
|
+
formData.append('type', 'image')
|
|
39
|
+
|
|
40
|
+
await useApipost(url, null, formData, { 'Content-Type': 'multipart/form-data' })
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. Upload with Progress Bar (`useApiProgress`)
|
|
44
|
+
|
|
45
|
+
If you need a progress bar, use `useApiProgress`. This function uses raw `XMLHttpRequest` under the hood.
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
import { useApiProgress } from '@/composable/fetch'
|
|
49
|
+
|
|
50
|
+
const formData = {
|
|
51
|
+
file: this.selectedFile,
|
|
52
|
+
type: 'video'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await useApiProgress(
|
|
56
|
+
'POST', // method
|
|
57
|
+
url, // url
|
|
58
|
+
formData, // payload (automatically grouped into FormData if opts.formData is true)
|
|
59
|
+
(progressEvent) => { // onProgress callback
|
|
60
|
+
console.log(`Uploaded ${progressEvent.percent}%`)
|
|
61
|
+
},
|
|
62
|
+
{ formData: true } // opts - If false, it gzip compresses JSON instead.
|
|
63
|
+
)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Rules
|
|
67
|
+
|
|
68
|
+
- **DO NOT** import `axios` directly in your components or Pinia stores.
|
|
69
|
+
- **DO NOT** manually construct `Authorization` headers. The wrappers handle this via cookies automatically.
|
|
70
|
+
- Always handle errors with `try...catch` or `.catch()` since these return Promises.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: builderx_spa-design
|
|
3
|
+
description: Standardized design system for BuilderX SPA. Covers Typography (text_design.scss), Forms (Input, Select, Checkbox), Layout (Table, Drawer, Modal), and Feedback (Button, Alert). Use this skill to build UI consistently using pre-built components instead of raw HTML/Tailwind.
|
|
4
|
+
metadata:
|
|
5
|
+
author: Vũ Lưu
|
|
6
|
+
version: "2026.3.24"
|
|
7
|
+
source: Hand-written based on @/components/design and text_design.scss
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# BuilderX SPA Design System
|
|
11
|
+
|
|
12
|
+
> â ïž **CRITICAL RULE:** Do NOT create custom CSS/SCSS for basic UI elements (text, buttons, inputs, modals). ALWAYS use the components and utility classes documented here.
|
|
13
|
+
|
|
14
|
+
## Core Concepts
|
|
15
|
+
|
|
16
|
+
| Topic | Description | Reference |
|
|
17
|
+
|-------|-------------|-----------|
|
|
18
|
+
| Typography | Headers, Body text, Colors, utility classes | [core-text-design](references/core-text-design.md) |
|
|
19
|
+
|
|
20
|
+
## UI Components
|
|
21
|
+
|
|
22
|
+
We use Ant Design Vue wrapped in custom components to enforce our design language.
|
|
23
|
+
**Cheat Sheet:** If you need a standard UI element, it likely exists in `@/components/design/[Name].vue` with standard AntD props + our custom props (like `label`, `message` for forms).
|
|
24
|
+
|
|
25
|
+
| Category | Available Components | Reference |
|
|
26
|
+
|----------|-----------------------|-----------|
|
|
27
|
+
| **Forms & Inputs** | `Input`, `Select`, `Checkbox`, `Radio`, `Switch`, `DatePicker`, `RangePicker` | [features-forms](references/features-forms.md) |
|
|
28
|
+
| **Layout & Data** | `Table`, `Tabs`, `Drawer`, `Modal`, `Sidebar`, `Pagination` | [features-layout-navigation](references/features-layout-navigation.md) |
|
|
29
|
+
| **Actions & Feedback** | `Button`, `Alert`, `Toastify`, `Badge`, `Empty`, `Tooltip` | [features-feedback-actions](references/features-feedback-actions.md) |
|
|
30
|
+
|
|
31
|
+
## General Usage Rule
|
|
32
|
+
```vue
|
|
33
|
+
<script setup>
|
|
34
|
+
// ALWAYS import from @/components/design, NOT generic antdv
|
|
35
|
+
import { Button, Input, Table } from '@/components/design'
|
|
36
|
+
</script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Tailwind CSS Integration
|
|
40
|
+
|
|
41
|
+
Absolutely **DO NOT** use custom CSS (custom classes in `<style>`) for layout and positioning. Combine the Design Component with **Tailwind CSS** to handle layout, spacing, sizing, and positioning.
|
|
42
|
+
|
|
43
|
+
**Usage Rules:**
|
|
44
|
+
1. **Design System Components:** Handle the functional logic and core UI/UX attributes (Example: `<Button>` controls color, hover effect, loading state).
|
|
45
|
+
2. **Tailwind CSS:** Handles layout via utility classes (e.g. `flex`, `gap-4`, `p-6`, `col-span-2`), spacing, sizing, and positioning.
|
|
46
|
+
|
|
47
|
+
### Example Integration:
|
|
48
|
+
|
|
49
|
+
```vue
|
|
50
|
+
<template>
|
|
51
|
+
<!-- Use Tailwind classes 'flex', 'gap-4', 'p-6', 'items-center' to design layout -->
|
|
52
|
+
<div class="flex flex-col gap-4 p-6 bg-white rounded-lg shadow-sm">
|
|
53
|
+
|
|
54
|
+
<div class="flex items-center justify-between">
|
|
55
|
+
<h2 class="text-design-h3-bold">User Information</h2>
|
|
56
|
+
<Button type="primary" label="Save Profile" @click="save" />
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<!-- 2-column Grid Layout using Tailwind -->
|
|
60
|
+
<div class="grid grid-cols-2 gap-4">
|
|
61
|
+
<!-- Input component scales to its parents grid item -->
|
|
62
|
+
<Input v-model:value="user.firstName" label="First Name" />
|
|
63
|
+
<Input v-model:value="user.lastName" label="Last Name" />
|
|
64
|
+
|
|
65
|
+
<!-- Force column spanning -->
|
|
66
|
+
<Input
|
|
67
|
+
class="col-span-2"
|
|
68
|
+
v-model:value="user.bio"
|
|
69
|
+
label="Biography"
|
|
70
|
+
isTextArea
|
|
71
|
+
/>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> ð¡ **Override Note:** Avoid overwriting internal styles of a Design Component. Before overriding UI, check for available props (such as size, type, or ghost). If you absolutely must override:
|
|
79
|
+
> 1. For small tweaks: Create a custom class and put it in your `<style scoped>` block.
|
|
80
|
+
> 2. For heavy customizations: Create a separate `[name]_custom_design.scss` file and import it, keeping the Vue file clean.
|
|
81
|
+
> **DO NOT** use `/deep/` or `::v-deep` directly on the component tag to brute-force styles.
|
|
82
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: core-text-design
|
|
3
|
+
description: Typography and color system using text_design.scss
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Typography & Colors
|
|
7
|
+
|
|
8
|
+
Always use the `.text-design-{level}-{weight}` utility classes or the `<Typography>` component. NEVER write custom `font-size`, `font-weight`, or `color` unless it's a completely unique case.
|
|
9
|
+
|
|
10
|
+
## 1. Utility Classes (Preferred)
|
|
11
|
+
|
|
12
|
+
Format: `text-design-[level]-[weight]`
|
|
13
|
+
|
|
14
|
+
**Levels (from text_design.scss):**
|
|
15
|
+
- `h0` (48px) â `h1` (38px) â `h2` (30px) â `h3` (24px) â `h4` (20px) â `h5` (16px)
|
|
16
|
+
- `body` (14px) â `body-sm` (13px)
|
|
17
|
+
- `footnote` (12px) â `footnote-sm` (10px)
|
|
18
|
+
|
|
19
|
+
**Weights:**
|
|
20
|
+
- `light` (300), `regular` (400), `medium` (500), `semibold` (600), `bold` (700)
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<!-- Example Usage -->
|
|
24
|
+
<h1 class="text-design-h3-bold text-center">Page Title</h1>
|
|
25
|
+
<p class="text-design-body-regular">Standard paragraph text.</p>
|
|
26
|
+
<span class="text-design-footnote-medium">Small note</span>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 2. Common Shorthands
|
|
30
|
+
`text_design.scss` provides several hardcoded shorthands with built-in colors:
|
|
31
|
+
|
|
32
|
+
- `.text-design-body-regular-light` (Muted/818789)
|
|
33
|
+
- `.text-design-link` / `.text-design-link-medium` / `.text-design-link-bold` (Brand color)
|
|
34
|
+
- `.text-design-link-open-medium` (Brand color, underlines on hover)
|
|
35
|
+
- `.text-design-body-neutral` / `.text-design-body-neutral-medium`
|
|
36
|
+
- `.text-design-neutral-strong` (Dark/404946)
|
|
37
|
+
- `.text-design-primary-600-14` (Brand green)
|
|
38
|
+
- `.text-design-white-medium` (White inverse)
|
|
39
|
+
|
|
40
|
+
## 3. SCSS Mixins
|
|
41
|
+
If you must write SCSS, use the mixins:
|
|
42
|
+
|
|
43
|
+
```scss
|
|
44
|
+
.my-card-title {
|
|
45
|
+
@include text-design(h4, bold);
|
|
46
|
+
color: var(--color-content-brand);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.my-subtitle {
|
|
50
|
+
@include text-design-body-medium; // Using shorthand mixin
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 4. Typography Component
|
|
55
|
+
```vue
|
|
56
|
+
<script setup>
|
|
57
|
+
import { Typography } from '@/components/design'
|
|
58
|
+
</script>
|
|
59
|
+
<template>
|
|
60
|
+
<Typography variant="h3" weight="bold" component="span">
|
|
61
|
+
Hello World
|
|
62
|
+
</Typography>
|
|
63
|
+
</template>
|
|
64
|
+
```
|