feat(deploy): production deployment setup and fixes

- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma
  binaryTargets for openssl 3.0
- nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal
  cron, http->https redirect
- prisma: add origin_goods.delisted migration, sync missing schema
  (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz
- api: CORS wildcard reflection, helmet CORP cross-origin, price
  backfill in persistProductDetail, categoryIcon ancestor fallback,
  mediaByColor per-color gallery in public goods detail
- admin: /admin base path (vite + router)
- import-data.mjs: udt_name casting, serial sequence advance fix
This commit is contained in:
yeuimu
2026-08-26 14:23:09 +08:00
parent be0b90e68f
commit 6c61a4e871
982 changed files with 74156 additions and 179393 deletions
@@ -1,203 +0,0 @@
---
title: Provide/Inject Has Limited DevTools Support - Plan for Debugging
impact: LOW
impactDescription: Unlike props and state, provided values are harder to trace in Vue DevTools, making debugging more challenging
type: gotcha
tags: [vue3, provide-inject, debugging, devtools, architecture]
---
# Provide/Inject Has Limited DevTools Support - Plan for Debugging
**Impact: LOW** - While provide/inject is powerful for avoiding prop drilling, it creates less visible data flow than props. Provided values are not as easily inspectable in Vue DevTools, and tracing where a value comes from requires navigating the component tree manually.
## Task Checklist
- [ ] Document provided values at the provider component level
- [ ] Use descriptive Symbol descriptions for easier identification
- [ ] Consider adding development-only logging for provided state changes
- [ ] Keep provide/inject chains shallow when possible
- [ ] Prefer Pinia for complex state that needs DevTools integration
## The Challenge
Unlike props which are clearly visible in Vue DevTools for each component, provided values:
1. Don't show which ancestor provided them
2. Require manual navigation to find the provider
3. Don't show in the standard props/data panels
4. Can be shadowed by closer ancestors using the same key
## Strategies for Better Debugging
### 1. Use Descriptive Symbol Names
```js
// injection-keys.js
// BETTER: Descriptive names appear in errors and debugging
export const UserAuthKey = Symbol('UserAuthenticationState')
export const ThemeConfigKey = Symbol('ThemeConfiguration')
export const FormContextKey = Symbol('FormValidationContext')
// WORSE: Generic names are harder to trace
export const UserKey = Symbol()
export const ThemeKey = Symbol('theme')
```
### 2. Document Providers Clearly
```vue
<!-- AuthProvider.vue -->
<script setup>
/**
* Authentication Provider
*
* Provides:
* - UserAuthKey: Current user state (Ref<User | null>)
* - AuthActionsKey: { login, logout, refresh }
*
* Must wrap any component that needs authentication state.
*/
import { provide, ref, readonly } from 'vue'
import { UserAuthKey, AuthActionsKey } from '@/injection-keys'
const user = ref(null)
// ... implementation
provide(UserAuthKey, readonly(user))
provide(AuthActionsKey, { login, logout, refresh })
</script>
```
### 3. Development-Only Logging
```js
// composables/useProvideWithLogging.js
import { provide, watch, getCurrentInstance } from 'vue'
export function useProvideWithLogging(key, value, name) {
provide(key, value)
if (import.meta.env.DEV) {
const instance = getCurrentInstance()
const componentName = instance?.type?.name || 'Unknown'
console.log(`[Provide] ${name} provided by <${componentName}>`)
// Log reactive changes
if (value && typeof value === 'object' && 'value' in value) {
watch(value, (newVal) => {
console.log(`[Provide] ${name} changed:`, newVal)
}, { deep: true })
}
}
}
```
```vue
<script setup>
import { ref } from 'vue'
import { useProvideWithLogging } from '@/composables/useProvideWithLogging'
import { ThemeKey } from '@/injection-keys'
const theme = ref('dark')
// In development, logs when provided and when changed
useProvideWithLogging(ThemeKey, theme, 'Theme')
</script>
```
### 4. Inject with Missing Provider Warnings
```js
// composables/useSafeInject.js
import { inject, getCurrentInstance } from 'vue'
export function useSafeInject(key, fallback, keyName) {
const value = inject(key, undefined)
if (value === undefined) {
const instance = getCurrentInstance()
const componentName = instance?.type?.name || 'Unknown'
if (import.meta.env.DEV) {
console.warn(
`[Inject] ${keyName || String(key)} not provided. ` +
`Component <${componentName}> is using fallback value. ` +
`Ensure a provider exists in the ancestor chain.`
)
}
return typeof fallback === 'function' ? fallback() : fallback
}
return value
}
```
```vue
<script setup>
import { useSafeInject } from '@/composables/useSafeInject'
import { ThemeKey } from '@/injection-keys'
// Warns in dev if no provider found
const theme = useSafeInject(ThemeKey, () => ({ mode: 'light' }), 'ThemeConfig')
</script>
```
### 5. Create Provider Registry for Complex Apps
```js
// utils/provider-registry.js
const providerRegistry = new Map()
export function registerProvider(key, componentName, value) {
if (import.meta.env.DEV) {
providerRegistry.set(key, {
componentName,
value,
timestamp: Date.now()
})
}
}
export function getProviderInfo(key) {
return providerRegistry.get(key)
}
// For DevTools custom plugin or debugging
export function getAllProviders() {
return Object.fromEntries(providerRegistry)
}
// Expose to window for console debugging
if (import.meta.env.DEV) {
window.__VUE_PROVIDERS__ = {
getAll: getAllProviders,
get: getProviderInfo
}
}
```
## When to Use Pinia Instead
If you find yourself needing extensive debugging for state:
| Use Provide/Inject | Use Pinia |
|-------------------|-----------|
| Component library internals | Application-wide state |
| Theme/locale configuration | User session data |
| Form context | Shopping cart |
| Simple parent-child sharing | Complex state with actions |
| Plugin configuration | State that needs time-travel debugging |
Pinia provides excellent DevTools integration with:
- State inspection
- Time-travel debugging
- Action logging
- Hot module replacement
## Reference
- [Vue DevTools](https://devtools.vuejs.org/)
- [Pinia DevTools](https://pinia.vuejs.org/core-concepts/index.html#devtools)