// GOOD: Public method designed for external use
// In UIManager:
public syncFiltersToUI(filters: Partial<FilterConfig>): void { ... }
// In LLMIntegration:
this.uiManager.syncFiltersToUI(filters); // OK, public API
Available Custom Events
trigger-search - Trigger a search
trigger-locate - Trigger a locate search
trigger-filter-refresh - Load airports matching current store filters
render-route - Render route on map
reset-rules-panel - Clear rules panel state
show-country-rules - Display country rules in Rules panel
airport-click - Trigger airport selection
display-airport-details - Display airport details in right panel
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: roznet-flyfun-apps-ui-review3description: UI Architecture Review4---56# UI Architecture Review78Review code changes in `web/client/ts/` for compliance with architecture principles.910## Architecture Rules11121. **Store is Single Source of Truth**:13 - All state lives in Zustand store (`ts/store/store.ts`)14 - No duplicated state in components15162. **State Updates via Actions**:17 - Use `store.getState().setX()` methods18 - Never direct assignment19203. **Component Communication Patterns**:21 - Store updates (primary method)22 - Custom events (cross-component actions)23 - Public API methods (limited, well-defined)24 - Never direct private method calls across components25264. **No Direct DOM Manipulation**:27 - Update store first28295. **Reactive Updates**:30 - UI/map updates via store subscriptions31 - Not manual calls after store updates32336. **Separation of Concerns**:34 - `UIManager` = UI/DOM handling only35 - `APIAdapter` = API communication only36 - `Store` = State management only37 - `VisualizationEngine` = Map rendering only38 - `LLMIntegration` = LLM orchestration only3940## Review Checklist4142### Store as Source of Truth43- All state updates use `store.getState().setX()` actions?44- No direct state manipulation?45- No duplicated state in components?4647### Component Communication48- LLMIntegration -> UIManager uses public APIs or events only?49- No private method calls across components?50- Cross-component updates go through store or events?5152### Separation of Concerns53- UIManager doesn't make direct API calls?54- APIAdapter doesn't manage state or manipulate DOM?55- Store doesn't contain business logic or UI code?5657### Reactive Updates58- UI updates happen via `store.subscribe()`?59- No manual `updateUI()` calls after `store.setX()`?6061## Red Flags6263Flag these violations immediately:6465- **Direct state assignment**: `state.airports = ...`, `state.filters.country = ...`66- **Direct DOM without store**: `element.value = ...` without `store.setSearchQuery()`67- **Private method calls**: `this.uiManager.handleSearch()` (handleSearch is private)68- **API calls outside APIAdapter**: `fetch(...)` in UIManager69- **Manual UI updates after store**: `updateUI()` right after `store.setX()`70- **Duplicated state**: Component maintains its own copy of store state71- **Tight coupling**: Direct instantiation like `new OtherComponent()`7273## Output Format7475**APPROVED:**76- `file:line` - Explanation of why it's correct7778**VIOLATION:**79- `file:line` - Description80- **Problem:** Why it violates architecture81- **Fix:** Suggested corrected implementation82- **Pattern:** Reference to approved pattern8384## Approved Patterns8586**Store Update Pattern:**87```typescript88// GOOD: Update store, components react via subscription89store.getState().setAirports(airports);90// UI updates automatically via store.subscribe() in UIManager91```9293**Event Pattern:**94```typescript95// GOOD: Loose coupling via events96window.dispatchEvent(new CustomEvent('trigger-search', {97 detail: { query: "EGKB LFPG" }98}));99```100101**Public API Pattern:**102```typescript103// GOOD: Public method designed for external use104// In UIManager:105public syncFiltersToUI(filters: Partial<FilterConfig>): void { ... }106107// In LLMIntegration:108this.uiManager.syncFiltersToUI(filters); // OK, public API109```110111## Available Custom Events112113- `trigger-search` - Trigger a search114- `trigger-locate` - Trigger a locate search115- `trigger-filter-refresh` - Load airports matching current store filters116- `render-route` - Render route on map117- `reset-rules-panel` - Clear rules panel state118- `show-country-rules` - Display country rules in Rules panel119- `airport-click` - Trigger airport selection120- `display-airport-details` - Display airport details in right panel121122## Reference123124- `designs/UI_FILTER_STATE_DESIGN.md` - Detailed examples125- `designs/CHATBOT_WEBUI_DESIGN.md` - LLM integration specifics126127---128> Converted and distributed by [TomeVault](https://tomevault.io/claim/roznet) — claim your Tome and manage your conversions.129<!-- tomevault:4.0:skill_md:2026-04-13 -->
Run npx skillmds@latest add tomevault-io/roznet-flyfun-apps-ui-review in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
UI Architecture Review It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
tomevault-io (@tomevault-io) published this skill. Their other Agent Skills are listed on their SkillMD profile.