Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ea0206f
初期DB、seed、modelを作成
tl-yoshirofujimaki Mar 11, 2025
0feb1fe
プランごとの電気料金を返すAPIを作成
tl-yoshirofujimaki Mar 11, 2025
e8e9196
tableに使われるenergyがエネルギー全般を指すため、電気エネルギーのみを指すelectricityに変更
tl-yoshirofujimaki Mar 11, 2025
3479ad4
例外処理を追加。developmentでのlog formatを追加
tl-yoshirofujimaki Mar 12, 2025
4c4c8e7
controllerのテストを追加、rubocop, rspecを導入
tl-yoshirofujimaki Mar 12, 2025
faccfda
modelのテストを追加
tl-yoshirofujimaki Mar 12, 2025
c72c496
frontendの初期構築(helloworldまで)
tl-yoshirofujimaki Mar 12, 2025
c2380ec
フロントエンドを作成。corsの制約をrails側に追記
tl-yoshirofujimaki Mar 12, 2025
76b8126
使用量計算のロジックが段階的な料金を考慮できていなかったため修正、min_usageとmax_usageの定義及びそれに伴うseedを修正
tl-yoshirofujimaki Mar 12, 2025
eb7491d
READMEを更新
tl-yoshirofujimaki Mar 12, 2025
a575723
電気料金シミュレーションで入力項目について説明するガイドを付与
tl-yoshirofujimaki Mar 12, 2025
c77257a
初期構築時にseedで読み込むデータをyaml管理するよう修正
tl-yoshirofujimaki Mar 13, 2025
c8a2a01
frontendとbackendでディレクトリを切り分け、本番稼働用の設定を追加
tl-yoshirofujimaki Mar 13, 2025
e5a1630
料金計算ロジックで小数点以下を切り捨てるよう修正、decimalでの精度を明示的に指定
tl-yoshirofujimaki Mar 14, 2025
83e530d
フロントでアンペア数をセレクタに変更、最安プランがわかるよう修正
tl-yoshirofujimaki Mar 14, 2025
b254833
READMEの更新
tl-yoshirofujimaki Mar 14, 2025
bb80fad
READMEのレスポンス項目で、各項目の記載を追記
tl-yoshirofujimaki Mar 14, 2025
b7df2eb
料金計算のテストを、小数点以下切り捨てを考慮したものへ修正。rubocop対応
tl-yoshirofujimaki Mar 14, 2025
c133220
providerの計算ロジックで不要な二重計算を修正、providerのテストコードを追加
tl-yoshirofujimaki Mar 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 1 addition & 29 deletions serverside_challenge_2/challenge/.gitignore
Original file line number Diff line number Diff line change
@@ -1,29 +1 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep

# Ignore uploaded files in development.
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/
!/tmp/storage/.keep

# Ignore master key for decrypting credentials and more.
/config/master.key
/copilot/*
225 changes: 212 additions & 13 deletions serverside_challenge_2/challenge/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,223 @@
# README
# 概要

This README would normally document whatever steps are necessary to get the
application up and running.
このアプリケーションは、指定した契約アンペア数および使用量に基づき、各電力プランの料金比較を行います

Things you may want to cover:
# バージョン情報

* Ruby version
- バックエンド
- Ruby `3.1.2`
- Rails `7.0.8`
- フロントエンド
- vue `3.5.13`
- vite `6.2.0`

* System dependencies
# ファイル構成

* Configuration
```
.
├── docker-compose.override.yml # 開発環境の時に上書きで利用するDocker設定
├── docker-compose.yml # 開発・本番環境のサービス定義とコンテナ設定
├── backend
│ └── Dockerfile # バックエンド (Rails) アプリケーションのDockerfile
└── frontend
├── Dockerfile # フロントエンド (Vue.js) アプリケーションの本番用Dockerfile
└── Dockerfile.dev # フロントエンド (Vue.js) アプリケーションの開発用Dockerfile
```

* Database creation
**※ バックエンド(Rails)のDockerfileは本番・開発用共通です**

* Database initialization
# ローカル環境構築手順

* How to run the test suite
1. Dockerコンテナを起動

* Services (job queues, cache servers, search engines, etc.)
```bash
docker compose up --build
```

* Deployment instructions
2. データベースを作成

* ...
```bash
docker compose run web rails db:create
```

3. マイグレーション実行


```bash
docker compose run web rails db:migrate
```

4. シードデータの投入

```bash
docker compose run web rails db:seed
```

# 本番デプロイ手順(aws)

1. Copilotのインストール

以下を参考に環境に合わせて実施
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/copilot-install.html

2. AWS環境の初期設定

```bash
aws configure
```

3. フロントエンドのデプロイ

```bash
copilot svc deploy --name frontend --env prod
```

4. バックエンドのデプロイ

```bash
copilot svc deploy --name web --env prod
```

**※ `copilot/` ディレクトリが必要ですが、機密情報が含まれるためコミット対象に含めておりません**
**そのため、本手順は参考としてご確認していただけたら幸いです。**
**どうするのが正解かは分かりませんが、本当の運用であれば機密情報の管理はAWS Systems Manager 等で管理すべきかと思います。**
Comment on lines +81 to +83
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

インフラのデプロイまでいただき、ありがとうございます!
AWS Copilotを採用した理由がありましたら、簡単に教えていただけますでしょうか?

Copy link
Author

@tl-yoshirofujimaki tl-yoshirofujimaki Mar 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RyuyaIshibashi
AWS Copilotを利用するに至った経緯ですが
まず、開発環境をDockerで構築していたため、本番環境も同様にコンテナで運用するのが望ましいと考え、デプロイ先としてECS + fargateを選択しました

次に、ECSへのデプロイ経験がなかったため、デプロイ方法の調査を進める中でAWS Copilotに行き着きました
Copilotは、ELBやVPC、ECRといった周辺インフラの構築からデプロイまで一貫して行えるため、素早く環境を構築したい状況に適していると考え、採用しました


# アプリケーションへのアクセス

http://localhost:5173

# アプリケーションの利用方法

- 以下項目を入力する
- 契約アンペア数(A)
- 1ヶ月の使用量(kWh)
- 計算するを押下する
- 正常な値を入力した場合
- 画面上に電力会社、プラン、料金(円)が表示される
- 不正な値を入力した場合
- エラーが表示される

# データベース設計

## テーブル一覧
- `providers` (電力会社情報)
- `plans` (電力会社ごとのプラン)
- `electricity_charges_basic_rates` (プランごとの基本料金)
- `electricity_charges_usage_rates` (プランごとの従量料金)

## テーブル詳細

### `providers` (電力会社情報)
| カラム名 | 型 | 制約 | 説明 |
|:---|:---|:---|:---|
| `id` | `bigint` | PK, NOT NULL | ID (主キー) |
| `name` | `string` | NOT NULL, UNIQUE | 会社名 |
| `created_at` | `datetime` | NOT NULL | 作成日時 |
| `updated_at` | `datetime` | NOT NULL | 更新日時 |

---

### `plans` (電力会社ごとのプラン)
| カラム名 | 型 | 制約 | 説明 |
|:---|:---|:---|:---|
| `id` | `bigint` | PK, NOT NULL | ID (主キー) |
| `provider_id` | `bigint` | FK, NOT NULL | 電力会社ID (外部キー) |
| `name` | `string` | NOT NULL, UNIQUE | プラン名 |
| `created_at` | `datetime` | NOT NULL | 作成日時 |
| `updated_at` | `datetime` | NOT NULL | 更新日時 |

---

### `electricity_charges_basic_rates` (プランごとの基本料金)
| カラム名 | 型 | 制約 | 説明 |
|:---|:---|:---|:---|
| `id` | `bigint` | PK, NOT NULL | ID (主キー) |
| `plan_id` | `bigint` | FK, NOT NULL, ampereとの複合UNIQUE | プランID (外部キー) |
| `ampere` | `integer` | NOT NULL, planとの複合UNIQUE | 契約アンペア数(A) |
| `basic_rate` | `decimal` | NOT NULL | 基本料金 (円) |
| `created_at` | `datetime` | NOT NULL | 作成日時 |
| `updated_at` | `datetime` | NOT NULL | 更新日時 |

---

### `electricity_charges_usage_rates` (プランごとの従量料金)
| カラム名 | 型 | 制約 | 説明 |
|:---|:---|:---|:---|
| `id` | `bigint` | PK, NOT NULL | ID (主キー) |
| `plan_id` | `bigint` | FK, NOT NULL | プランID (外部キー) |
| `min_usage` | `integer` | NOT NULL | 電気使用量(kWh)の下限値 (境界値を含まない) |
| `max_usage` | `integer` | NULL許可 | 電気使用量(kWh)の上限値 (境界値を含む) |
| `unit_rate` | `decimal` | NOT NULL | 従量料金単価 (円/kWh) |
| `created_at` | `datetime` | NOT NULL | 作成日時 |
| `updated_at` | `datetime` | NOT NULL | 更新日時 |

# API

## 電力料金計算API

### エンドポイント

```
GET /electricity_prices
```

### リクエストパラメータ

| パラメータ | 必須 | 説明 | 例 |
| -- | -- | -- | -- |
| ampere | ○ | 契約アンペア数 (10/15/20/30/40/50/60のいずれか) | 30 |
| usage | ○ | 使用量 (0以上の整数) | 200 |

### レスポンス

#### データ形式
- レスポンス形式: JSON
- データの並び順: ID の昇順で返却

---

#### 各項目の説明
- `provider_name` : 電力会社の名称
- `plan_name`: 電気料金プランの名称
- `price`: 料金 (円) 小数点以下は切り捨て

---

#### レスポンス例 (成功時)

```json
[
{
"provider_name": "東京電力エナジーパートナー",
"plan_name": "従量電灯B",
"price": "5648"
},
{
"provider_name": "東京ガス",
"plan_name": "ずっとも電気1",
"price": "5890"
}
]
```

#### レスポンス例 (エラー時)

```json
{
"error": "アンペア数(ampere)は 10/15/20/30/40/50/60 のいずれかを指定してください"
}

```

# テストの実行

## フロントエンド
未実装

## バックエンド

rspecを導入しており、以下のコマンドでテスト実行できます

```
docker compose run web rspec
```

This file was deleted.

This file was deleted.

29 changes: 29 additions & 0 deletions serverside_challenge_2/challenge/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep

# Ignore uploaded files in development.
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/
!/tmp/storage/.keep

# Ignore master key for decrypting credentials and more.
/config/master.key
2 changes: 2 additions & 0 deletions serverside_challenge_2/challenge/backend/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--require spec_helper
--format documentation
8 changes: 8 additions & 0 deletions serverside_challenge_2/challenge/backend/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Style/Documentation:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/BlockLength:
Enabled: false
Layout/FirstHashElementIndentation:
Enabled: false
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app
ADD . /app
CMD ["bash", "-c", "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"]
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
source "https://rubygems.org"
# frozen_string_literal: true

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.1.2"
ruby '3.1.2'

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.8"
gem 'rails', '~> 7.0.8'

# Use postgresql as the database for Active Record
gem "pg", "~> 1.1"
gem 'pg', '~> 1.1'

# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 5.0"
gem 'puma', '~> 5.0'

# Build JSON APIs with ease [https://github.com/rails/jbuilder]
# gem "jbuilder"
Expand All @@ -25,24 +27,26 @@ gem "puma", "~> 5.0"
# gem "bcrypt", "~> 3.1.7"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false
gem 'bootsnap', require: false

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem "rack-cors"
gem 'rack-cors'

group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri mingw x64_mingw ]
gem 'debug', platforms: %i[mri mingw x64_mingw]
gem 'factory_bot_rails'
gem 'rspec-rails', '~> 7.0'
end

group :development do
# Speed up commands on slow machines / big apps [https://github.com/rails/spring]
# gem "spring"
gem 'rubocop-rails', require: false
end

Loading