Getting Started

Welcome to StructEngine-v2 development! This guide will help you set up your environment, understand the project structure, and start working with calculators.

Project Setup

### Prerequisites

  • Python 3.9+ (project uses Python 3.11)

  • Poetry (for dependency management)

  • Node.js 16+ and npm (for frontend)

  • Git

### Clone and Install

  1. Clone the repository:

    git clone https://github.com/im-ashok/structengine-v2.git
    cd structengine-v2
    
  2. Install backend dependencies:

    poetry install
    
  3. Activate virtual environment:

    poetry shell
    
  4. Install frontend dependencies:

    cd web
    npm install
    cd ..
    

Running the Application

### Backend (FastAPI)

Start the API server:

poetry run uvicorn api.main:app --reload --port 8000

The API will be available at http://localhost:8000

API documentation (Swagger UI): http://localhost:8000/docs

### Frontend (Vue.js)

In a separate terminal:

cd web
npm run dev

The frontend will be available at http://localhost:5173

Using Calculators

### API Endpoint Pattern

All calculators follow this pattern:

POST /api/calculators/{calculator_type}/calculate

Available calculator types: - section_properties (Analysis) - beam_analysis (Analysis) - beam_design (Concrete, IS 456) - column_design (Concrete, IS 456) - slab_design (Concrete, IS 456) - crack_width (Concrete, IS 456) - base_plate (Steel, IS 800) - steel_column (Steel, IS 800)

### Example API Call (Beam Design)

Python:

import requests

# Beam design input (IS 456:2000)
payload = {
    "beam_type": "rectangular",
    "width": 300,  # mm
    "depth": 500,  # mm
    "span": 6000,  # mm
    "concrete_grade": "M25",
    "steel_grade": "Fe415",
    "dead_load": 25,  # kN/m
    "live_load": 15,  # kN/m
    "clear_cover": 25  # mm
}

response = requests.post(
    "http://localhost:8000/api/calculators/beam_design/calculate",
    json=payload
)

result = response.json()
print(f"Required steel: {result['main_bars_description']}")

cURL:

curl -X POST "http://localhost:8000/api/calculators/beam_design/calculate" \\
     -H "Content-Type: application/json" \\
     -d '{
       "beam_type": "rectangular",
       "width": 300,
       "depth": 500,
       "span": 6000,
       "concrete_grade": "M25",
       "steel_grade": "Fe415",
       "dead_load": 25,
       "live_load": 15,
       "clear_cover": 25
     }'

Adding New Calculators

### Step 1: Create Calculator Module

Create a new Python file in the appropriate module directory:

  • api/app/calculators/analysis/ for analysis tools

  • api/app/calculators/concrete/ for IS 456 concrete design

  • api/app/calculators/steel/ for IS 800 steel design

### Step 2: Implement BaseCalculator

from api.app.calculators.base import BaseCalculator, CalculationError
from pydantic import BaseModel, Field
from typing import Type

class MyCalculatorInput(BaseModel):
    """Input schema with Google/NumPy docstring style."""

    dimension: float = Field(..., gt=0, description="Dimension in mm")
    load: float = Field(..., description="Load in kN")

class MyCalculatorOutput(BaseModel):
    """Output schema."""

    result: float = Field(..., description="Result in kN-m")
    status: str = Field(..., description="PASS or FAIL")

class MyCalculator(BaseCalculator):
    """
    Calculator for [purpose] per IS [code]:[year].

    References IS [code]:[year] Clause [X.Y.Z] for [calculation].
    """

    def __init__(self) -> None:
        super().__init__("my_calculator", "1.0.0")

    @property
    def input_schema(self) -> Type[BaseModel]:
        return MyCalculatorInput

    @property
    def output_schema(self) -> Type[BaseModel]:
        return MyCalculatorOutput

    def calculate(self, inputs: dict) -> dict:
        """
        Perform calculation.

        Args:
            inputs: Validated input dictionary

        Returns:
            Output dictionary with results

        Raises:
            CalculationError: If calculation fails
        """
        # Your calculation logic here
        result = inputs["dimension"] * inputs["load"]

        return {
            "inputs": inputs,
            "result": result,
            "status": "PASS" if result < 100 else "FAIL"
        }

### Step 3: Register in Router

Add to api/app/routers/calculators.py:

from api.app.calculators.module.my_calculator import MyCalculator

# Register calculator
router.add_calculator(MyCalculator())

### Step 4: Add Tests

Create api/tests/calculators/test_my_calculator.py:

import pytest
from api.app.calculators.module.my_calculator import MyCalculator

def test_my_calculator():
    calc = MyCalculator()
    result = calc.calculate({
        "dimension": 100,
        "load": 50
    })
    assert result["status"] == "FAIL"  # 100 * 50 = 5000 > 100

Documentation Standards

### Docstring Style

Use Google/NumPy style docstrings for all functions, classes, and methods:

def calculate_moment(force: float, arm: float) -> float:
    """
    Calculate bending moment per IS 456:2000 Clause 22.2.

    Args:
        force: Applied force in kN
        arm: Moment arm in mm

    Returns:
        Bending moment in kN-m

    Raises:
        ValueError: If force or arm is negative

    Example:
        >>> calculate_moment(100, 500)
        50.0

    Note:
        Units: kN, mm, MPa, kN-m (consistent with IS codes)
    """
    if force < 0 or arm < 0:
        raise ValueError("Force and arm must be positive")
    return force * arm / 1000

### IS Code References

Always include IS code references in docstrings:

  • Format: IS [code]:[year] Clause [X.Y.Z]

  • Examples: - IS 456:2000 Clause 26.5.1.1 (flexure) - IS 800:2007 Clause 7.4.3 (bearing) - IS 875:1987 (Part 1) (dead loads)

### Type Hints

Use strict type hints for all function signatures:

from typing import Dict, List, Tuple, Optional

def analyze_section(
    width: float,
    depth: float,
    material: str
) -> Dict[str, float]:
    """Type hints are mandatory."""
    pass

### Docstring Coverage

Maintain 80%+ coverage with interrogate:

poetry run interrogate api/app/calculators/ -vv

Pre-commit hook will fail if coverage drops below 80%.

Testing Your Changes

### Run Tests

# All tests
poetry run pytest

# Specific module
poetry run pytest api/tests/calculators/concrete/

# With coverage
poetry run pytest --cov=api/app/calculators

### Pre-commit Hooks

Before committing, pre-commit hooks will run:

  • ruff (linting and formatting)

  • mypy (type checking)

  • interrogate (docstring coverage)

  • bandit (security scan)

  • gitleaks (secret detection)

Install hooks:

poetry run pre-commit install

Next Steps

  • Review Architecture to understand system design

  • Follow Tutorials for practical examples

  • Explore Calculators API for complete API reference

  • Check IS code standards: IS 456:2000, IS 800:2007, IS 875:1987

Need Help?

  • API Documentation: http://localhost:8000/docs (Swagger UI)

  • Code Review: Submit PR with detailed description and test coverage

  • IS Code Questions: Reference official IS code documents in docs/references/