# @decocms/start — Framework TODO

Issues discovered during the portal-davinci migration script development.

---

## Tier 0 — Blocking migrations

### `setup.ts` should be framework-injected
- **Current**: Every site has a `setup.ts` with identical boilerplate (import.meta.glob, registerSections, setBlocks, registerBuiltinMatchers)
- **Ideal**: Site declares only its custom loaders/actions. Framework injects the rest via Vite plugin or a single `createSiteSetup()` call
- **Impact**: Migration script has to scaffold this file. Any framework change requires re-migrating all sites

### `SiteTheme` component missing from `@decocms/start` or `@decocms/apps`
- **Current**: `apps/website/components/Theme.tsx` was removed. Migration script scaffolds a local replacement
- **Ideal**: Export `SiteTheme` from `@decocms/start/components/Theme` or `@decocms/apps/commerce/components/Theme`
- **Impact**: Every migrated site gets a local copy that diverges over time

---

## Tier 1 — Developer experience

### `useScript(fn)` hydration mismatch warning
- **Current**: `useScript` calls `fn.toString()` which produces different output in SSR vs client builds (minification, variable renaming)
- **Warning**: `[useScript] Using fn.toString() for "setup". This may produce different output in SSR vs client builds`
- **Ideal**: Provide `inlineScript()` that accepts a plain string constant, or make `useScript` stable across builds
- **Impact**: Console noise in every dev session, potential hydration bugs in production

### Route files are 100% boilerplate
- **Files**: `__root.tsx`, `index.tsx`, `$.tsx`, `deco/meta.ts`, `deco/invoke.$.ts`, `deco/render.ts`
- **Current**: Migration script scaffolds identical route files for every site
- **Ideal**: Framework provides a `createDecoRoutes()` or auto-generates via Vite plugin. Site only customizes (e.g. GTM ID, site name)
- **Impact**: Route files are copy-pasted across sites and diverge

### `server.ts`, `worker-entry.ts`, `router.tsx` are boilerplate
- **Current**: Every site has identical server infrastructure files
- **Ideal**: Single function call like `createDecoServer()` / `createDecoRouter()`. Or auto-generated by Vite plugin
- **Impact**: Sites copy these files and never update them when framework improves

### `dev:clean` script should be built into framework
- **Current**: Migration script adds `"dev:clean": "rm -rf node_modules/.vite .wrangler/state .tanstack && vite dev"`
- **Ideal**: `@decocms/start` CLI command or Vite plugin hook that auto-cleans stale caches on startup
- **Impact**: Developers hit mysterious caching bugs and don't know to clean

---

## Tier 2 — Quality & correctness

### GTM/Analytics SDK is duplicated across sites
- **Current**: Every site has a custom `Session.tsx` with identical analytics SDK (data-event listeners, data-gtm-event listeners, IntersectionObserver)
- **Ideal**: `@decocms/start/analytics` exports a `<DecoAnalytics gtmId="GTM-XXX" />` component used in `__root.tsx`
- **Impact**: Analytics bugs are fixed per-site instead of once in the framework

### `useGTMEvent` hook is universal
- **Current**: Sites have a local `sdk/useGTMEvent.ts` that creates `data-gtm-event` / `data-gtm-trigger` attributes
- **Ideal**: Export from `@decocms/start/analytics/useGTMEvent`
- **Impact**: Same utility duplicated in every site

### Negative z-index (`-z-10`) breaks in Tailwind v4 stacking contexts
- **Current**: Migration script auto-fixes `-z-N` → `z-0` on images and adds `relative z-10` to content siblings
- **Root cause**: React/TanStack wraps sections in `<section>` elements that create new stacking contexts. Negative z-index gets trapped inside
- **Ideal**: Document this pattern. Consider framework-level CSS reset that prevents section wrappers from creating stacking contexts (e.g. `section { isolation: auto; }`)
- **Impact**: Every migrated site has background images that are invisible until manually fixed

### Tailwind v3 → v4 opacity classes
- **Current**: Migration script converts `bg-black bg-opacity-20` → `bg-black/20`
- **Edge cases**: Non-adjacent opacity classes (e.g. `bg-black flex ... hover:bg-opacity-30`) are harder to detect
- **Ideal**: Provide a lint rule or postcss plugin that warns about orphaned opacity classes
- **Impact**: Subtle visual bugs that are hard to spot

---

## Tier 3 — Nice to have

### `registerLayoutSections` auto-detection
- **Current**: Migration script detects Header/Footer/Theme by name pattern and adds to `registerLayoutSections()`
- **Ideal**: Framework auto-detects layout sections from CMS page structure (sections that appear on every page = layout)
- **Impact**: New sections added as layout require manual setup.ts update

### Icon loaders (`availableIcons.ts`, `icons.ts`) depend on deleted `static/adminIcons.ts`
- **Current**: Migration script deletes these loaders entirely
- **Ideal**: Framework provides a built-in icon discovery mechanism (scan `public/sprites.svg` at build time)
- **Impact**: Admin loses icon picker functionality after migration

### `import.meta.glob` section discovery could be smarter
- **Current**: Glob `./sections/**/*.tsx` discovers all files, including utility exports
- **Ideal**: Use a convention (e.g. default export = section) or a marker comment to distinguish sections from helpers
- **Impact**: Non-section files in `sections/` directory get registered as CMS sections

---

## Discovered during migration (portal-davinci)

| Issue | Where | Status |
|-------|-------|--------|
| `scriptAsDataURI` → `useScript` leaves malformed JSX | `fresh-apis.ts` | Fixed in script |
| `.test()` then `.replace()` regex bug (lastIndex statefulness) | All transforms | Fixed in script |
| `site/` → `~/` doesn't strip `.tsx` extension | `imports.ts` | Fixed in script |
| `class` in destructuring/interface not converted to `className` | `jsx.ts` | Fixed in script |
| `for=` → `htmlFor=` missing | `jsx.ts` | Fixed in script |
| `tabindex` → `tabIndex` missing | `jsx.ts` | Fixed in script |
| Multi-line `className={clx()}` z-index insertion fails | `tailwind.ts` | Fixed in script |
| `src/` directory scanned as source → `src/src/` created | `phase-analyze.ts` | Fixed in script |
| `package.json`/`package-lock.json` treated as source files | `phase-analyze.ts` | Fixed in script |
| `constants.ts` not deleted | `phase-analyze.ts` | Fixed in script |
| `deno-lint-ignore` in JSX comments not removed | `deno-isms.ts` | Fixed in script |
| `useDevice` import not split from `useScript` module | `imports.ts` | Fixed in script |
| `@decocms/start/worker` wrong path → `@decocms/start/sdk/workerEntry` | `server-entry.ts` | Fixed in script |
| `SiteTheme` / `Font` import removed by catch-all rule | `imports.ts` | Fixed in script |
| Bootstrap failures silently ignored | `migrate.ts` | Fixed in script |

---

## Fast Deploy (KV-first content) — cross-repo follow-ups

Framework + CI scripts landed in this repo (see [`docs/fast-deploy.md`](./docs/fast-deploy.md)). Remaining work lives in other repos:

- **admin.deco.cx (Studio)**: publish a delta envelope to `/.decofile` + call `/_cache/purge`; gate on a per-site `fast_deploy_enabled` capability; dispatch deco-sync-bot commit off the critical path.
- **Site CI**: provision KV namespace + `DECO_KV` binding; add `sync-content-to-kv.yml`; gate `deploy.yml` to code-only changes.
- **Framework follow-up**: module-level `loadBlocks()` consumers (e.g. `loadRedirects` in worker-entry) read the bundled snapshot pre-hydration — move into request path to fast-deploy them.
