Node.js で小規模なアプリケーションを開発する方法 その5

# 日報管理システムでやりたいこと
システムで解決したい下記に記載します (正直エクセル使いましょうよ(笑)って感じですが、どうしてもWebアプリにしたいお客様がいると仮定します、大変ありがたいことです)

- プロジェクトごとに全体＋工程別の予定工数、実績工数、残工数、消費率を知りたい

# 使用者の分類
管理者のみとします。当初の計画通り、管理者とメンバーの2種類に分けようと思ったのですが、目的を達成することを考えると不要と思い、管理者のみとした次第です。

# 権限
管理者は下記の操作が可能であるとします。

- 全てのプロジェクトの一覧表示、詳細表示、新規作成、修正、削除
- 全ての案件の一覧表示、詳細表示、新規作成、修正、削除

# データ構造の定義

## 管理者情報
管理者情報を管理者情報ID、ユーザ名、パスワードを格納するデータ構造と定義します。

## プロジェクト
プロジェクトをプロジェクトID、番号、名称、カテゴリ配列、予定工数(人時)を格納するデータ構造と定義します。

## カテゴリ
カテゴリを名称と予定工数(人時)を格納するデータ構造と定義します。

## 日報
日報を日報ID、プロジェクトID、日付、開始時刻、終了時刻、作業時間、カテゴリ、タイトル、メモを格納するデータ構造と定義します。

## システム設定
システム設定をシステム設定ID、キー、バリューを格納するデータ構造と定義します。

# モデルの追加
```app/models``` に下記のファイルを追加します。

- project.js
- report.js
- setting.js

```js:project.js
'use strict';

module.exports = function (sequelize, DataTypes) {
  var Project = sequelize.define('Project', {
    name: DataTypes.STRING,
    categories: DataTypes.TEXT,
    day: DataTypes.DECIMAL,
  }, {
    classMethods: {
      associate: function (models) {
        Project.hasMany(models.Report)
      },
    },
  })

  return Project
}

```

```js:report.js
'use strict';

module.exports = function (sequelize, DataTypes) {
  var Report = sequelize.define('Report', {
    date: DataTypes.DATEONLY,
    start: DataTypes.TIME,
    finish: DataTypes.TIME,
    hour: DataTypes.DECIMAL,
    category: DataTypes.STRING,
    title: DataTypes.STRING,
    memo: DataTypes.TEXT,
  }, {
    classMethods: {
      associate: function (models) {
        Report.belongsTo(models.Project)
      },
    },
  })

  return Report
}

```

```js:setting.js
'use strict';

module.exports = function (sequelize, DataTypes) {
  var Setting = sequelize.define('Setting', {
    key: DataTypes.STRING,
    value: DataTypes.TEXT,
  })

  return Setting
}

```

```app``` ディレクトリで ```npm run sync``` をしてSQLを確認します。

# フィクスチャの追加
```app/test/fixture``` に下記のファイルを追加します。

- projects.js
- reports.js
- settings.js

```js:projects.js
'use strict';

module.exports = function (models) {
  return models.Project.bulkCreate([
    {
      id: 1,
      index: 1,
      name: '日報管理システム',
      categories: JSON.stringify([
        '見積',
        '契約',
        '計画',
        'ディレクション',
        '画面作成',
        '画面点検補助',
        '設計仕様書作成',
        '設計仕様書点検補助',
        'ソースコード作成',
        'ソースコード点検補助',
        '初期設定',
      ]),
      day: 10.0,
    },
    {
      id: 2,
      index: 2,
      name: '会社紹介ホームページ',
      categories: JSON.stringify([
        '見積',
        '契約',
        '計画',
        'ディレクション',
        'ワイヤーフレーム作成',
        'ワイヤーフレーム点検補助',
        'ラフデザイン作成',
        'ラフデザイン点検補助',
        'プロトタイプ作成',
        'プロトタイプ点検補助',
        '制作仕様書作成',
        '制作仕様書点検補助',
        'ソースコード作成',
        'ソースコード点検補助',
        '初期設定',
      ]),
      day: 8.5,
    },
  ])
}

```

```js:reports.js
'use strict';

module.exports = function (models) {
  return models.Report.bulkCreate([
    {
      id: 1,
      date: '2015-10-18',
      start: '09:00:00',
      finish: '10:00:00',
      hour: 1.0,
      category: '見積',
      title: '見積書作成',
      memo: '途中',
      ProjectId: 1,
    },
    {
      id: 2,
      date: '2015-10-18',
      start: '13:00:00',
      finish: '13:30:00',
      hour: 0.5,
      category: '見積',
      title: '見積書作成',
      memo: '完了',
      ProjectId: 1,
    },
    {
      id: 3,
      date: '2015-10-19',
      start: '16:00:00',
      finish: '17:15:00',
      hour: 1.25,
      category: '契約',
      title: '契約書作成',
      memo: '基本契約書のみ完了',
      ProjectId: 1,
    },
  ])
}

```

```js:settings.js
'use strict';

module.exports = function (models) {
  return models.Setting.bulkCreate([
    {
      id: 1,
      key: 'default-categories',
      value: JSON.stringify([
        {
          name: 'Webアプリケーション開発',
          categories: [
            '見積',
            '契約',
            '計画',
            'ディレクション',
            '画面作成',
            '画面点検補助',
            '設計仕様書作成',
            '設計仕様書点検補助',
            'ソースコード作成',
            'ソースコード点検補助',
            '初期設定',
          ],
        },
        {
          name: 'ホームページ制作',
          categories: [
            '見積',
            '契約',
            '計画',
            'ディレクション',
            'ワイヤーフレーム作成',
            'ワイヤーフレーム点検補助',
            'ラフデザイン作成',
            'ラフデザイン点検補助',
            'プロトタイプ作成',
            'プロトタイプ点検補助',
            '制作仕様書作成',
            '制作仕様書点検補助',
            'ソースコード作成',
            'ソースコード点検補助',
            '初期設定',
          ],
        }
      ]),
    },
  ])
}

```

```fixture/index.js``` を編集します

```js:fixture/index.js(編集前)
'use strict';

module.exports = function (models) {
  var Promise = models.Sequelize.Promise

  return Promise.all([
    require('./administrator')(models),
  ])
}

```

```js:fixture/index.js(編集後)
'use strict';

module.exports = function (models) {
  var Promise = models.Sequelize.Promise

  return Promise.all([
    require('./administrator')(models),
    require('./projects')(models),
    require('./settings')(models),
  ])
    .then(function () {
      return Promise.all([
        require('./reports')(models),
      ])
    })
}

```

```app``` ディレクトリで ```npm run sync``` をしてSQLを確認します。

# おわりに
明日はURL設計を行います。