7.7 KiB
Style Preset UI Only Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Make page style presets affect generated UI tokens only, without changing generated page canvas/layout.
Architecture: Keep automatic layout selection inside PageCompositionService.chooseLayout(). Resolve the selected PageStylePreset only to write stylePreset, styleTokens, and composition metadata into layout JSON. Remove the canvas override path so presets cannot change table/card/split/dense layout structure.
Tech Stack: Java, JUnit 4, Jackson, Spring service classes in ruoyi-generator.
File Structure
- Modify:
ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageCompositionServiceStylePresetTest.java- Owns regression tests for
PageCompositionServicestyle preset behavior.
- Owns regression tests for
- Modify:
ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/PageCompositionService.java- Owns deterministic page canvas selection and layout JSON composition.
- Modify:
ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageStylePresetRegistryTest.java- Owns registry contract tests for style tokens, density, and fallback.
- Modify:
ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/PageStylePresetRegistry.java- Owns available visual preset definitions.
Task 1: Lock Style Presets Out Of Canvas Selection
Files:
-
Modify:
ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageCompositionServiceStylePresetTest.java -
Modify:
ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/PageCompositionService.java -
Step 1: Write the failing frontend regression test
Replace cardPortalPresetPrefersCardCanvasForFrontendLists with:
@Test
public void cardPortalPresetKeepsAutomaticallySelectedFrontendCanvas()
{
FrontProjectPageDesign design = design("frontend", "list");
service.compose(design, table(), Arrays.asList(
column("title", "title", "1", "1", "1"),
column("status", "status", "1", "1", "1")), null, null, true, "card_portal");
Map<String, Object> layout = readLayout(design);
assertEquals("frontend-list-v1", layout.get("canvas"));
assertEquals("card_portal", layout.get("stylePreset"));
assertTrue(((Map<?, ?>) layout.get("styleTokens")).containsKey("primary"));
Map<?, ?> composition = (Map<?, ?>) layout.get("composition");
assertEquals("card_portal", composition.get("stylePreset"));
assertTrue(String.valueOf(composition.get("reasons")).contains("card_portal"));
}
- Step 2: Write the failing admin regression test
Replace dataDensePresetPrefersDenseCanvasForAdminLists with:
@Test
public void dataDensePresetKeepsAutomaticallySelectedAdminCanvas()
{
FrontProjectPageDesign design = design("admin", "list");
service.compose(design, table(), Arrays.asList(
column("code", "code", "1", "1", "1"),
column("name", "name", "1", "1", "1")), null, null, true, "data_dense");
Map<String, Object> layout = readLayout(design);
assertEquals("admin-list-v1", layout.get("canvas"));
assertEquals("data_dense", layout.get("stylePreset"));
assertTrue(((Map<?, ?>) layout.get("styleTokens")).containsKey("primary"));
}
- Step 3: Run tests to verify they fail
Run:
mvn -pl ruoyi-generator -Dtest=PageCompositionServiceStylePresetTest test
Expected: both tests fail because the current implementation changes canvas to frontend-list-card-v1 and admin-list-dense-v1.
- Step 4: Implement minimal service change
In PageCompositionService.compose(...), replace:
stylePreset = stylePresetRegistry.resolve(stylePresetCode);
applyStylePreset(decision, pageType, scope, stylePreset);
with:
stylePreset = stylePresetRegistry.resolve(stylePresetCode);
decision.addReason("style preset " + stylePreset.getCode() + " applied visual tokens");
Then remove the unused applyStylePreset(...) method.
- Step 5: Run tests to verify they pass
Run:
mvn -pl ruoyi-generator -Dtest=PageCompositionServiceStylePresetTest test
Expected: Tests run: 2, Failures: 0, Errors: 0.
Task 2: Remove Canvas Mapping From The Registry Contract
Files:
-
Modify:
ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageStylePresetRegistryTest.java -
Modify:
ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/PageStylePresetRegistry.java -
Step 1: Write the failing registry contract test
Replace resolvesKnownPresetWithCanvasAndTokens with:
@Test
public void resolvesKnownPresetWithTokensOnly()
{
PageStylePresetRegistry registry = new PageStylePresetRegistry();
PageStylePresetRegistry.PageStylePreset preset = registry.resolve("card_portal");
assertEquals("card_portal", preset.getCode());
assertEquals("#167d83", preset.token("primary", ""));
assertEquals("#f6c85b", preset.token("accent", ""));
assertEquals("comfortable", preset.getDensity());
assertTrue(registry.options().size() >= 4);
}
Replace unknownPresetFallsBackToBusinessClean with:
@Test
public void unknownPresetFallsBackToBusinessCleanTokens()
{
PageStylePresetRegistry registry = new PageStylePresetRegistry();
PageStylePresetRegistry.PageStylePreset preset = registry.resolve("not_real");
assertEquals("business_clean", preset.getCode());
assertEquals("#167d83", preset.token("primary", ""));
assertEquals("1200px", preset.token("contentWidth", ""));
}
- Step 2: Run registry test before implementation
Run:
mvn -pl ruoyi-generator -Dtest=PageStylePresetRegistryTest test
Expected: test compilation fails after removing frontend/admin canvas assertions from tests only if production still exposes unused API is not a compile failure; if tests pass immediately, continue with the cleanup as refactor under the Task 1 green state.
- Step 3: Remove registry canvas API and definitions
In PageStylePresetRegistry, remove:
private final Map<String, String> frontendCanvases = new LinkedHashMap<String, String>();
private final Map<String, String> adminCanvases = new LinkedHashMap<String, String>();
Remove all .frontend(...) and .admin(...) calls from preset definitions. Remove the private builder methods frontend(...) and admin(...). Remove public methods frontendCanvas(...) and adminCanvas(...).
- Step 4: Run registry tests
Run:
mvn -pl ruoyi-generator -Dtest=PageStylePresetRegistryTest test
Expected: Tests run: 2, Failures: 0, Errors: 0.
Task 3: Final Verification
Files:
-
Test:
ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageCompositionServiceStylePresetTest.java -
Test:
ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageStylePresetRegistryTest.java -
Step 1: Run focused tests together
Run:
mvn -pl ruoyi-generator -Dtest=PageCompositionServiceStylePresetTest,PageStylePresetRegistryTest test
Expected: both test classes pass.
- Step 2: Inspect diff for scope
Run:
git diff -- ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/PageCompositionService.java ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/PageStylePresetRegistry.java ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageCompositionServiceStylePresetTest.java ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/PageStylePresetRegistryTest.java
Expected: diff only changes style preset canvas coupling and corresponding tests.