From c37bae0453be2934e866c308ea0d6c8b2c334878 Mon Sep 17 00:00:00 2001 From: Alex Perez Date: Thu, 26 Feb 2026 13:33:18 -0300 Subject: [PATCH 01/13] docs: add team documentation and development patterns @W-21315032 - Add docs/team/ structure for patterns, configs, runbooks - Add Web Component communication pattern documentation - Add debugging runbook for common issues - Add .claude/ folder to .gitignore for local AI-generated files This establishes team knowledge base with: - Web Components best practices (properties, events, Shadow DOM) - Common debugging scenarios and solutions - Development workflow guidelines - Testing patterns Benefits: - Onboard new contributors faster - Document tribal knowledge - Consistent patterns across components - Context preservation for AI assistants Work Item: @W-21315032 --- .gitignore | 5 +- docs/team/README.md | 38 +++ .../00-web-component-communication.md | 191 ++++++++++++ .../runbooks/00-debugging-common-issues.md | 278 ++++++++++++++++++ 4 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 docs/team/README.md create mode 100644 docs/team/patterns/00-web-component-communication.md create mode 100644 docs/team/runbooks/00-debugging-common-issues.md diff --git a/.gitignore b/.gitignore index a87a2540f..ad8e34988 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,7 @@ demo/models/flattened/*.json .idea/ .sfdx -.codegenie \ No newline at end of file +.codegenie +# Claude/Cursor working files +.claude/ +.cursor/ diff --git a/docs/team/README.md b/docs/team/README.md new file mode 100644 index 000000000..c245cf796 --- /dev/null +++ b/docs/team/README.md @@ -0,0 +1,38 @@ +# API Console Team Shared Documentation + +This directory contains **team-shared** documentation and configurations. +These files ARE committed to Git and shared with all team members and community contributors. + +## Structure + +- `patterns/` - Code patterns, architectural decisions (Web Components, LitElement) +- `configs/` - Team configuration files (IDE settings, linters, etc.) +- `runbooks/` - Operational guides (release process, debugging, common issues) + +## Usage + +### For AI Assistants (Claude/Cursor) +When starting work on this repo, read: +``` +Read docs/team/patterns/*.md +Read docs/team/runbooks/*.md +``` + +### For Team Members & Contributors +1. Add new patterns when making architectural decisions +2. Update runbooks when solving common issues +3. Share configs that improve team productivity + +## Difference vs `.claude/` +- `.claude/` = Personal, local, NOT committed (your drafts) +- `docs/team/` = Shared, committed, team knowledge base + +## Context + +**api-console** is an open-source project: +- LitElement/Polymer Web Components +- Distributed as separate npm packages +- Used by MuleSoft, Salesforce, and external developers +- Shadow DOM, custom events, AMF integration + +Document patterns that help new contributors understand how to work with this codebase. diff --git a/docs/team/patterns/00-web-component-communication.md b/docs/team/patterns/00-web-component-communication.md new file mode 100644 index 000000000..13bf03280 --- /dev/null +++ b/docs/team/patterns/00-web-component-communication.md @@ -0,0 +1,191 @@ +# Pattern: Web Component Communication + +**Date**: 2026-02-26 +**Author**: ACM Team +**Status**: Accepted +**Applies to**: All Web Components in api-console + +--- + +## Problem + +Web Components in api-console need to communicate with each other: +- Parent → Child: Pass data down +- Child → Parent: Notify of events +- Sibling → Sibling: Share state + +Without clear patterns, components become tightly coupled and hard to test. + +--- + +## Solution + +Use **Properties + Custom Events** pattern: + +``` +┌─────────────────────────────────────┐ +│ Parent Component │ +│ - Sets properties on children │ +│ - Listens to custom events │ +└──────────────┬──────────────────────┘ + │ + │ properties (down) + ▼ +┌─────────────────────────────────────┐ +│ Child Component │ +│ - Receives data via @property │ +│ - Emits custom events (up) │ +└─────────────────────────────────────┘ +``` + +--- + +## Implementation + +### Parent → Child (Properties) + +**Parent sets property**: +```javascript +// parent-component.js +import { LitElement, html } from 'lit-element'; + +class ParentComponent extends LitElement { + render() { + return html` + + + `; + } +} +``` + +**Child receives property**: +```javascript +// api-navigation.js +import { LitElement, html } from 'lit-element'; + +class ApiNavigation extends LitElement { + static get properties() { + return { + amf: { type: Object }, + selected: { type: String } + }; + } + + updated(changedProps) { + if (changedProps.has('amf')) { + this._processAmf(this.amf); + } + } +} +``` + +### Child → Parent (Custom Events) + +**Child dispatches event**: +```javascript +// api-navigation.js +_handleSelection(endpointId) { + this.dispatchEvent(new CustomEvent('api-navigation-selection-changed', { + bubbles: true, + composed: true, + detail: { selected: endpointId } + })); +} +``` + +**Parent listens to event**: +```javascript +// parent-component.js +render() { + return html` + + + `; +} + +_onSelectionChanged(e) { + this.selectedId = e.detail.selected; +} +``` + +### Sibling → Sibling (Shared State) + +**Option 1: State in parent** (preferred for simple cases): +```javascript +// parent manages state, passes to both children +class ParentComponent extends LitElement { + render() { + return html` + + + + + + `; + } +} +``` + +**Option 2: Event bus** (for complex cases): +```javascript +// Avoid unless absolutely necessary - harder to debug +``` + +--- + +## Rules + +### ✅ DO +- Use `.property` syntax for Object/Array properties (not attributes) +- Use `bubbles: true, composed: true` for events that cross shadow DOM +- Prefix event names with component name (`api-navigation-*`) +- Document event details in JSDoc +- Keep event payloads simple (primitives, plain objects) + +### ❌ DON'T +- Don't access child component methods directly (`this.querySelector('api-nav').selectEndpoint()`) +- Don't use global variables for component communication +- Don't mutate objects passed as properties (create new objects instead) +- Don't listen to events on `window` unless truly global + +--- + +## Example from Codebase + +See `api-console/src/ApiConsole.js` for complete parent-child pattern: +- Properties: `amf`, `selected`, `baseUri` +- Events: `api-navigation-selection-changed`, `api-request-send` + +--- + +## Testing + +```javascript +import { fixture, html } from '@open-wc/testing'; + +it('emits selection event when item clicked', async () => { + const el = await fixture(html``); + + setTimeout(() => el._handleSelection('endpoint-1')); + const event = await oneEvent(el, 'api-navigation-selection-changed'); + + expect(event.detail.selected).to.equal('endpoint-1'); +}); +``` + +--- + +## Related +- [Shadow DOM Styling Pattern](./01-shadow-dom-styling.md) +- [AMF Integration Pattern](./02-amf-integration.md) + +--- + +**Last Updated**: 2026-02-26 diff --git a/docs/team/runbooks/00-debugging-common-issues.md b/docs/team/runbooks/00-debugging-common-issues.md new file mode 100644 index 000000000..02b71572e --- /dev/null +++ b/docs/team/runbooks/00-debugging-common-issues.md @@ -0,0 +1,278 @@ +# Runbook: Debugging Common Issues + +**Project**: api-console (Open Source) +**Last Updated**: 2026-02-26 + +--- + +## Quick Links + +- **Demo**: `npm start` → http://localhost:8080 +- **Tests**: `npm test` +- **Repo**: https://github.com/mulesoft/api-console +- **Issues**: https://github.com/mulesoft/api-console/issues + +--- + +## Common Issues + +### Issue 1: Component Not Rendering + +**Symptoms**: Component shows nothing, or only skeleton + +**Diagnosis**: +1. Check browser console for errors +2. Check if `amf` property is set +3. Check if component is registered (`customElements.get('api-console')`) +4. Inspect Shadow DOM in DevTools + +**Common Causes**: +- AMF not loaded or invalid +- Async rendering not complete +- CSS not loaded (check for `