Skip to content

Common Development Tasks

Step-by-step guides for recurring development workflows.


Task 1: Adding a New Component Type

Scenario: You want to add a new category of RF components (e.g., "phase_shifter")

Steps

  1. Create backend database directory:

    mkdir backend/categorized_databases/phase_shifter
    mkdir backend/categorized_databases/phase_shifter/1_6ghz
    mkdir backend/categorized_databases/phase_shifter/6_18ghz
    # ... other frequency bands
    

  2. Add component JSON files:

    // backend/categorized_databases/phase_shifter/1_6ghz/HMC939.json
    {
      "part_number": "HMC939",
      "manufacturer": "Analog Devices",
      "type": "phase_shifter",
      "frequency_min_ghz": 0.5,
      "frequency_max_ghz": 6.0,
      "phase_shift_deg": 360,
      "insertion_loss_db": 4.5,
      "datasheet_url": "https://www.analog.com/...",
      "package": "QFN-16",
      "price_usd": 15.50,
      "in_stock": true
    }
    

  3. Update category index:

    # Edit backend/categorized_databases/category_index.json
    # Add "phase_shifter" to the categories list
    

  4. Create AI agent (optional but recommended):

    # backend/agents/simple_phase_shifter_agent.py
    from typing import List, Dict
    from .base_agent import BaseAgent
    
    class SimplePhaseShifterAgent(BaseAgent):
        def select(self, requirements: Dict, candidates: List[Dict]) -> Dict:
            # Selection logic with scoring
            scores = []
            for component in candidates:
                score = self._calculate_score(component, requirements)
                scores.append((component, score))
    
            # Sort by score and return best match
            best = sorted(scores, key=lambda x: x[1], reverse=True)[0]
            return best[0]
    
        def _calculate_score(self, component: Dict, requirements: Dict) -> float:
            frequency_score = self._score_frequency_match(component, requirements)
            phase_score = self._score_phase_range(component, requirements)
            return frequency_score * 0.6 + phase_score * 0.4
    

  5. Add frontend selection service:

    // frontend/src/services/component/phaseShifter/phaseShifterSelection.ts
    import { Component, SelectionRequirements } from '../../../types/rfComponents';
    
    export const selectPhaseShifter = (
      candidates: Component[],
      requirements: SelectionRequirements
    ): Component | null => {
      const filtered = candidates.filter(c =>
        c.frequency_min_ghz <= requirements.frequency &&
        c.frequency_max_ghz >= requirements.frequency &&
        c.phase_shift_deg >= requirements.minPhaseShift
      );
    
      if (filtered.length === 0) return null;
    
      // Score and select best match
      const scored = filtered.map(c => ({
        component: c,
        score: calculatePhaseShifterScore(c, requirements)
      }));
    
      return scored.sort((a, b) => b.score - a.score)[0].component;
    };
    

  6. Test:

    # Start servers
    .\start-all-servers-windowed.ps1
    
    # Test API endpoint
    curl -X POST http://localhost:8000/api/agent/select/phase_shifter \
      -H "Content-Type: application/json" \
      -d '{"frequency_ghz": 2.4, "min_phase_shift": 180}'
    


Task 2: Modifying Component Selection Logic

Scenario: You want to adjust PA selection to prioritize efficiency over cost

Steps

  1. Edit the AI agent:

    # backend/agents/simple_pa_agent.py
    
    def _calculate_score(self, component, requirements, weights=None):
        if weights is None:
            weights = {
                "frequency_match": 0.25,
                "power_capability": 0.30,
                "efficiency": 0.35,  # Increased from 0.25
                "cost": 0.10         # Decreased from 0.20
            }
    
        # ... rest of scoring logic
    

  2. Test with custom weights:

    curl -X POST http://localhost:8000/api/agent/select/pa \
      -H "Content-Type: application/json" \
      -d '{
        "frequency_ghz": 2.4,
        "output_power_dbm": 30,
        "weights": {
          "frequency_match": 0.25,
          "power_capability": 0.30,
          "efficiency": 0.35,
          "cost": 0.10
        }
      }'
    

  3. Verify results in FastAPI docs at http://localhost:8000/docs


Task 3: Adding a New Export Format

Scenario: You want to export to Altium Designer format

Steps

  1. Create export utility:

    # backend/utils/altium_export.py
    from typing import Dict, List
    import json
    
    class AltiumExporter:
        def __init__(self, rf_chain: Dict):
            self.rf_chain = rf_chain
    
        def export(self) -> bytes:
            """Generate Altium .PcbDoc format (simplified example)"""
            altium_data = self._convert_to_altium_format()
            return self._serialize(altium_data)
    
        def _convert_to_altium_format(self) -> Dict:
            # Conversion logic
            pass
    

  2. Add route:

    # backend/routes/exports.py
    from ..utils.altium_export import AltiumExporter
    
    @router.post("/altium")
    async def export_altium(rf_chain: dict):
        try:
            exporter = AltiumExporter(rf_chain)
            altium_file = exporter.export()
    
            return Response(
                content=altium_file,
                media_type="application/octet-stream",
                headers={"Content-Disposition": "attachment; filename=rf_module.PcbDoc"}
            )
        except Exception as e:
            logger.error(f"Altium export failed: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    

  3. Create frontend service:

    // frontend/src/services/export/altiumExportService.ts
    import axios from 'axios';
    
    export const exportToAltium = async (rfChain: any): Promise<Blob> => {
      const response = await axios.post(
        `${import.meta.env.VITE_FASTAPI_URL}/api/exports/altium`,
        rfChain,
        { responseType: 'blob' }
      );
      return response.data;
    };
    

  4. Add UI button in export component


Task 4: Updating PCB Stackup Logic

Scenario: Add support for PTFE-based materials

Steps

  1. Add material to database:

    // frontend/src/data/materials.ts (if not using backend materials API)
    // OR add via API endpoint
    

  2. Update impedance calculations:

    // frontend/src/utils/impedance/impedanceCalculatorUtils.ts
    export const calculateMicrostripImpedance = (
      width: number,
      height: number,
      dk: number,
      frequency: number // Add frequency-dependent dk for PTFE
    ): number => {
      // Update calculation for PTFE's unique characteristics
      const effectiveDk = calculateEffectiveDk(dk, width, height, frequency);
      // ... rest of calculation
    };
    

  3. Update type definitions if needed:

    // frontend/src/types/material.ts
    export interface Material {
      name: string;
      dk: number;
      df: number;
      dk_frequency_dependent?: boolean; // New field
      dk_coefficients?: number[];       // For PTFE
      // ... other fields
    }
    

  4. Test calculations with PTFE materials


Task 5: Adding Documentation

Scenario: Document a new feature

Steps

  1. User guide (for end users):

    # Create in docs/guides/
    touch docs/guides/PHASE_SHIFTER_GUIDE.md
    

  2. Technical documentation (for developers):

    # Create in docs/ or root
    touch PHASE_SHIFTER_IMPLEMENTATION.md
    

  3. Update main documentation index:

    # docs/index.md
    ## New Features
    - [Phase Shifter Component Selection](guides/PHASE_SHIFTER_GUIDE.md)
    

  4. API documentation: Auto-generated by FastAPI at /docs endpoint