Master checklist for finishing the Baukasten feature. We tackle open items one at a time, each
with its own focused plan. Status: [x] done · [~] in progress · [ ] open.
permissions, config-reader, api facade, config-ui picker, playgroundgetProjectListData) + picker show/hide + responsive UIbaukastenConfigurations, load-order)PrepareSave → main save() → wholesale update; schema field presentLayoutConfigReaderService.readMergedBaukastenConfig(configurations)merge(...) (top = base, bottom wins, no reversal);merge / readMergedLayoutConfig untouched.data/test/json and run npm run debug:json-merge.)WebUIController.readLayoutConfigwebuiProject === "baukasten" → BaukastenService.readConfigurations(refs) →readMergedBaukastenConfig(...) → return); reuses the legacy layout.json route (no routeConfigurationManager.merge now surfaces baukastenConfigurations onto the mergedcustomMailService: bottom-most defining entry wins, encoded, never raw.baukasten-data\client_logic (copy of_logic_layout_1, retargeted: projectId "baukasten", outDir ../client, empty source body,code-splitting.ts brought in; the global SASS + global locales integrated into client_logicsrc/style/global/, locales-global/) so it's self-contained — no _logic_global/_globalt/baukasten/). pnpm install && pnpm run build-prod therebaukasten-data\client. (Dev links kept; build is the user's to run.)WebUIController: view servesclientDir/index.html when webuiProject === "baukasten"; getReadFilePath resolves/webui-content/{token}/t/baukasten/… assets under clientDir (with a traversal guard).style/* + tokenWorker.js unchanged (per-customer).14243/public/layout1.json (rootquery:"#main" → fv-layout recreating the layout_1 body regions + nested fv-webvieweriframe-content), registered via a 14243/fileinfo.json layout1 entrybase/secret/77001 stubs left untouched). Also closed a step-B gap: added aWebUIController.readLayoutStylings so config/styles.json{styles:[]} — the client's if (layout && styles) render guard now passes.global: truegetProjectListData), so webui_theme_mode is saved true and the client's config requests use/webui/t/baukasten/config/... route (was 404-ing on the one-segment /webui/baukasten/...).getThemePath andgetModularSystemPath — only transitionally relocated to clientDir.fv-layout styleability + layout_1 grid. Finished the generic fv-layout primitivefurnview-components): createNodeElement now applies the slot key (and data.class) as regionpart (so configs target regions via .content/::part(content));render parts the container; layout.component.sass gives baseline :host/.layout-container--fv-layout-* CSS-custom-property API (house pattern). Resolves E's dead-data.classlayout1.json now carries the responsive layout_1 grid in customCSS_logic_layout_1/layout.sass, regions placed by grid-area) + --fv-layout-height:100vhstyleVars. Component stays generic (each layout config supplies its own grid). (Needs afv-layout.createRenderRoot now returns thelight-dom attribute is present, else shadow (default unchanged).#main, so legacy configs'areas (targeting region classes) resolve. Toggled by a new adapter config14243/public/layout1-lightdom-adapter.json (registered in fileinfo.json) that merges onto the base'sfv-layout (by tag+index, root query:"body"): +properties adds light-dom, -modules drops+areas re-adds it as an.iframe-content area (resolves in both modes). layout1.json itself is untouched (standalone uselayout1 → layout1-lightdom-adapter → legacy content.LayoutConfigReaderService.updateRootquery differs from the base's (the oldupdateModuleOrArea bail at 445-446). When source.query is set and differs from the merged root's,updateModuleAreaOrChildren(target, {areas:[source]}, "areas", "query", [])), so at render loadArea#main → the fv-layout scaffold container,modules load before root areas). Same/undefined root query →#main). Closes L's open reconciliationisStoreMember via FurncloudCredential.StoreTree. Replaced the () => false stub inBaukastenService with an async resolver: loads the OWNER credential and returns whether thekdnr_dh in owner.StoreTree.Stores (confirmed shape:{ Stores: [{ kdnr_dh, firma, … }] }, the same data CustomerController.getStoreTree/IStoreTreeawaits it per store-owner, so async/DB is fine; graceful when an ownerpublic/private/self/owner/consumer access untouched.WebUIController.readThemeConfig: it loads theme.json from the configured clientDirconfig/theme.json) and _.merges the config's webui_theme_config, returning the merged theme —getProjectPathName couldn't reach for the syntheticbaukasten project (so it had been 500-ing). The client already applies it via the sharedTemplateLoaderService (construction:initialize → fetch themeConfig → :root color vars +template/config-id options), so no client change. (Server-only JS — furnplan_web reload.)article-url-configurator.tsonWebUIModeDropDownChanged so the themeConfig fetch + buildWebUIThemeConfig run once for every#webUIThemeOptions), so webui_theme_config is UI-editable and round-tripsgetWebUIThemeConfigJson/prepareSave path; category filters stay modular-only.client_logic into the baukasten monorepo. Relocated the Vite client source intobaukasten/apps/client (new apps/ workspace glob; package @dh-software/baukasten-client), registeredpackage.json + pnpm-workspace.yaml (added autoInstallPeers + the client's dev-link overrides,client_logic/pnpm-workspace.yaml and depth-corrected for the monorepo root).vite.config.ts outDir builds directly into the served client dir../../../baukasten-data/client = Config.furnview.baukasten.clientDir), so build:prod writes thepnpm install at the monorepopnpm --filter @dh-software/baukasten-client run build:prod, then deletes the oldbaukasten-data/client_logic.)fv-layout: omit <slot>s in light-DOM mode. layout.component.ts render() computesemitSlots = !this.hasAttribute("light-dom") and threads it through traverseDefinition into the staticcreateNodeElement, which now appends the region <slot name=…> only when emitSlots is true. Shadowpart still applied in both modes. (Needs a furnview-components +14243/public/layout2.json — recreates legacy layout_2 via fv-layoutlogo column, header, 3-part sidebar catalog-header/catalog-content/catalog-footer, andcontent with fv-webviewer slotted directly into .content + toolbar/price/logo overlays;layout2-lightdom-adapter.json (grafts.content with prepend, since layout_2 has no .iframe-content). Also renamed thelightdom-adapter → layout1-lightdom-adapter for symmetry; both registered infileinfo.json. layout2.json's customCSS is a full faithful port of layout_2's layout.sass (all--var with its default, the .no-logo/.no-catalog-header/… modifier variants,baukasten/{lib, dist}. Consolidated the former sibling folders: the wholebaukasten/lib/, and the runtime data (configurations/ + built client/) underbaukasten/dist/. Updated furnview.js (configurationsDir/clientDir → baukasten\dist\…),lib/apps/client/vite.config.ts outDir → ../../../dist/client, and the lib/pnpm-workspace.yamllib/, data under dist/ (e.g. baukasten-data/client →baukasten/dist/client; baukasten/apps/client → baukasten/lib/apps/client). furnplan_web's twofile: deps re-pointed packages/* → lib/packages/*. The pre-restructure content (old monorepo +baukasten-data/) was archived under baukasten/old/, now deleted after verification. (Done.)fv-layout: rework the component CSS. Revisit the :host / .layout-container / .node.layout-container wrapper so the grid lives directly on theonBtnSaveConfigurationAsClick / onBtnSaveTemplateAsClick) POST only the inner .configuration toUseCaseConfigurationController.create, which persists only {customerNo, externalConf, configuration, isTemplate, name} — so the top-level baukastenConfigurations (set byBaukastenConfigSelection.PrepareSave) is dropped. But the modular fields (modularLayout /modularLayoutRootConfigurations / modularLayoutLayoutConfigurations / modularStylings, writtenWebUiLayoutSelection.PrepareSave) are dropped the same way — so baukasten isUseCaseConfigurationModel.createcreate template. (Normal Save works — it PUTs the whole openedConfiguration to update.)@dh-software/baukasten + @dh-software/baukasten-config-uinpm.furnco.de (replace the file: deps); propagate the furncloud-models schema change;_furnview bundle.fileinfo.json + configisStoreMember after the global store-system rework. The current resolver readsFurncloudCredential.StoreTree.Stores[].kdnr_dh; once the planned global rework of thetheme.json) was per-layout historicallybin_layout_1/config vs bin_layout_2/config), but baukasten has one shared client folder, so M'sclientDir/config/theme.json can't serve both. No easy, self-contained approach was found, sotheme.json, whichclient_logic into the monorepo may make a client-side approachreadThemeConfig re-reads the base config'stheme — fragile config re-read + base-first assumption; (2) full merge in readThemeConfig + sharedreadLayoutConfig strip + AUC ?a=<id> — too many changes; (3) theme rides in layout.json,webui-api:event/events.ts, service/template.service.ts; webui-configuration-parser:types/construction.types.ts, service/construction.service.ts) + a webui_theme_config bake-in inreadLayoutConfig, needing a webui-core build/publish + client rebuild. Key facts for the revisit: thetheme; getConfiguration needs ?a= (the AUC theme fetch lackswebui_theme_config client-side while the runtime does it server-side;client_logic consumes webui-core as versioned deps.