# Issue #01: プロジェクト構造とCI/CD設定

**Phase:** 1a
**優先度:** 最高（最初に実装）
**依存関係:** なし
**見積もり:** 0.5日

---

## 概要

Railway Frameworkのプロジェクト構造を作成し、CI/CD環境を整備する。
TDD開発の基盤となるテスト環境も含めて構築する。

---

## TDD実装手順

### Step 1: Red（テストを書く）

```python
# tests/unit/test_project_structure.py
"""Test project structure and imports."""
import pytest


class TestProjectImports:
    """Test that all modules can be imported."""

    def test_import_railway(self):
        """Should be able to import railway package."""
        import railway
        assert railway is not None

    def test_import_railway_core(self):
        """Should be able to import core modules."""
        from railway.core import decorators
        from railway.core import pipeline
        from railway.core import config
        assert decorators is not None
        assert pipeline is not None
        assert config is not None

    def test_import_railway_cli(self):
        """Should be able to import CLI modules."""
        from railway.cli import main
        assert main is not None

    def test_version_defined(self):
        """Should have version defined."""
        import railway
        assert hasattr(railway, '__version__')
        assert railway.__version__ == "0.1.0"
```

```bash
# 実行して失敗を確認
pytest tests/unit/test_project_structure.py -v
# Expected: FAILED (ModuleNotFoundError)
```

### Step 2: Green（最小限の実装）

```bash
# ディレクトリ構造を作成
mkdir -p railway/{cli,core,templates/{project,entry,node},utils}
mkdir -p tests/{unit/{core,cli},integration,e2e}
touch railway/__init__.py
touch railway/cli/__init__.py
touch railway/core/__init__.py
touch railway/utils/__init__.py
```

```python
# railway/__init__.py
"""Railway Framework for Python."""
__version__ = "0.1.0"

# railway/core/__init__.py
"""Core functionality."""

# railway/core/decorators.py
"""Decorators for Railway nodes and entry points."""

# railway/core/pipeline.py
"""Pipeline execution."""

# railway/core/config.py
"""Configuration provider registry."""

# railway/cli/__init__.py
"""CLI commands."""

# railway/cli/main.py
"""Main CLI entry point."""
```

```bash
# 実行して成功を確認
pytest tests/unit/test_project_structure.py -v
# Expected: PASSED
```

### Step 3: Refactor

- 不要なファイルを削除
- docstringを追加
- __all__ を定義

---

## 成果物

### ディレクトリ構造

```
railway_py/
├── railway/
│   ├── __init__.py           # パッケージ定義、バージョン
│   ├── cli/
│   │   ├── __init__.py
│   │   └── main.py           # typer app
│   ├── core/
│   │   ├── __init__.py
│   │   ├── config.py         # 設定プロバイダー（空）
│   │   ├── decorators.py     # デコレータ（空）
│   │   ├── pipeline.py       # パイプライン（空）
│   │   ├── errors.py         # エラー型（空）
│   │   └── types.py          # 型定義（空）
│   ├── templates/
│   │   ├── project/
│   │   ├── entry/
│   │   └── node/
│   └── utils/
│       ├── __init__.py
│       └── file_ops.py       # ファイル操作（空）
├── tests/
│   ├── unit/
│   │   ├── core/
│   │   └── cli/
│   ├── integration/
│   ├── e2e/
│   └── conftest.py
├── pyproject.toml
├── .github/
│   └── workflows/
│       └── ci.yml
└── README.md
```

### pyproject.toml

```toml
[project]
name = "railway-framework"
version = "0.1.0"
description = "Railway Oriented Programming framework for Python"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
    "returns>=0.22.0",
    "tenacity>=8.2.0",
    "pydantic>=2.5.0",
    "pydantic-settings>=2.1.0",
    "typer>=0.9.0",
    "loguru>=0.7.0",
    "python-dotenv>=1.0.0",
    "PyYAML>=6.0",
    "Jinja2>=3.1.0",
]

[project.optional-dependencies]
dev = [
    "ruff>=0.1.0",
    "mypy>=1.7.0",
    "pytest>=7.4.0",
    "pytest-cov>=4.1.0",
    "pytest-asyncio>=0.21.0",
]

[project.scripts]
railway = "railway.cli.main:app"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.ruff]
line-length = 100
target-version = "py310"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP"]

[tool.mypy]
python_version = "3.10"
strict = true
ignore_missing_imports = true

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--strict-markers -v"
asyncio_mode = "auto"

[tool.coverage.run]
source = ["railway"]
branch = true

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "if TYPE_CHECKING:",
    "raise NotImplementedError",
]
```

### .github/workflows/ci.yml

```yaml
name: CI

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12"]

    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python ${{ matrix.python-version }}
        run: uv python install ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --all-extras

      - name: Lint with ruff
        run: uv run ruff check .

      - name: Type check with mypy
        run: uv run mypy railway/

      - name: Test with pytest
        run: uv run pytest --cov=railway --cov-report=xml

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml
```

---

## 完了条件

- [ ] ディレクトリ構造が作成されている
- [ ] `import railway` が成功する
- [ ] `railway.__version__` が "0.1.0" を返す
- [ ] pytest が実行できる
- [ ] ruff check が通る
- [ ] mypy が通る（ignore_missing_imports）
- [ ] CI/CDが設定されている

---

## 次のIssue

- #02: 設定プロバイダーレジストリ
