愛記システムの基本設計:DApps側である愛記システム 愛の行動の促進 フィードバックと報酬 | 続・ティール組織 研究会のブログ

続・ティール組織 研究会のブログ

ティール組織が話題になっているが、具現化するにはどうしたらよいか?
その研究を続けるにあたり、さらに次の形態である、続・ティール組織なるものまで視野に入れ、具体的な施策・行動内容を研究・支援する会。

先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。概念設計としてはひとまず終えた。次は、フェデレーションモデル全体の基本設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。そして、それにつながるDApps側である「愛記システム」を、Pythonプログラムで開発していきたい。

 

愛の行動のPL,BSを決算書として、個人単位、市町村単位、で公表するような愛記システムというものを考えている。愛の行動のデータベースはブロックチェーンのプログラムであり、日々の愛の行動による愛貨の移動を決算書にまとめていきたい。なお、市町村のブロックチェーンのプログラムは以前にも記載している。その市町村のブロックチェーンのプログラムにつながる愛記システムを、DApps側であるPythonプログラムとして設計したい。その場合、基本設計をどのような手順で進めていけばよいか、詳しく見ていこう。

 

愛記システムを設計するための基本手順を以下に示す。このシステムは、Pythonを用いて市町村のブロックチェーンと連携し、個人および市町村単位での愛の行動のデータを収集、記録し、決算書(PL、BS)として公表するものである。

基本設計のステップ

  1. 要件定義
  2. アーキテクチャ設計
  3. データベース設計
  4. API設計
  5. ブロックチェーンインターフェース
  6. 決算書の生成
  7. フロントエンド開発
  8. テストとデプロイ

基本設計の各ステップを順番に進めることで、ブロックチェーンとDAppsとして繋がる「愛記システム」の詳細な設計が可能になる。各ステップでは、関係者との協議やレビューを通じて設計内容を確定していくことが重要である。

1.要件定義

まず、基本設計の最初のステップである要件定義をしていきたい。どのような機能が必要か、どのような問題を解決するのかを洗い出したい。要件定義はシステム設計の最初の重要なステップであり、システムが解決するべき問題と、必要な機能を明確に定義するプロセスである。以下に、愛記システムのプログラムに必要な機能と解決すべき問題を列挙してみよう。

機能要件

  1. 愛の行動の記録

  2. 愛貨の移動の記録

  3. 決算書の生成

  4. 個人および市町村単位でのデータの集約

  5. データのブロックチェーンへの記録と取得

  6. 愛貨の管理

  7. ユーザー管理

  8. 通知機能

  9. レポート機能

  10. ダッシュボード

非機能要件

  1. セキュリティ

  2. 可用性

  3. パフォーマンス

  4. スケーラビリティ

  5. ユーザビリティ

  6. コンプライアンス

解決すべき問題

  1. 透明性と信頼性の確保

  2. データの一元管理

  3. 愛の行動の促進

  4. 評価制度の確立

  5. データのセキュリティとプライバシーの保護

これらの要件を基に、愛記システムの基本設計を進めていくことが重要である。次のステップでは、これらの要件を具体的なアーキテクチャ設計に反映していくことになる。まずは、要件定義の解決すべき問題を一つずつクリアにしていきたい。

愛の行動の促進

愛の行動の促進は、愛記システムの主要な目的の一つである。これを達成するためには、ユーザーが積極的に愛の行動を取る動機付けを行い、その行動を記録し、報酬やフィードバックを提供する必要がある。以下に具体的な設計案を示す。

1. 動機付けのタイミングと方法

タイミング

  • 新規ユーザー登録時: ウェルカムメッセージと初回ボーナス
  • 定期的なリマインダー: 日々のリマインダー通知
  • 特別なイベント時: 特定のイベントやキャンペーン

方法

  • 通知機能: アプリやメールによるリマインダーと通知
  • 報酬制度: ポイントや愛貨のボーナス
  • ランキングシステム: ユーザー同士の競争心を刺激

2. 愛の行動の記録

タイミング

  • ユーザーが愛の行動を行ったとき: 即時に記録
  • 他者がユーザーの行動を認証したとき: 承認後に記録

方法

  • モバイルアプリまたはWebポータル: ユーザーが愛の行動を入力
  • QRコードスキャン: 簡単に行動を記録

3. フィードバックと報酬

タイミング

  • 行動記録時: 行動の記録後即時
  • 定期的な報酬: 週次・月次の集計に基づく報酬

方法

  • 受信者からの報酬: 愛貨受信者からモノやお金で与えられる報酬
  • 企業からの報酬: 特定の行動に対する愛貨の報酬

4. コミュニティの形成

タイミング

  • 定期的なイベント: 月次・年次のイベント
  • 特別な達成時: 特定の目標を達成した時

方法

  • フォーラム: ユーザー同士が交流できるフォーラム
  • イベント: オンラインまたはオフラインのイベントの開催
  • チャレンジ: ユーザーが参加できるチャレンジやミッション
     

フィードバックと報酬システムの設計

1. 行動記録時のフィードバックと報酬 について

・タイミング: 相手が愛貨を受領した直後 

・方法: 愛貨のやりとりとは別に、相手から、報酬(モノやお金)を受け取る 

・流れ: 相手が愛貨を受領時 市町村のブロックチェーンからDAppsに受領が通知され、愛貨の増減がなされる。この直後に別のDApps側である報酬システムから受信者が入っていき、報酬の種類・内容・金額を選択して送信者に送る。このようなDApps側であるPythonプログラムを設計して、別のデータベースに、報酬の記録を行っていく。

 

以下の設計は、行動記録時のフィードバックと報酬についての詳細なDApps側でのPythonプログラムと、報酬を管理するための別のデータベースの設計を示す。

全体の流れ:

  1. 愛貨の受領通知

    • 相手が愛貨を受領すると、市町村のブロックチェーンがDAppsに受領を通知する。
  2. 報酬システムへの誘導

    • 愛貨の受領直後、別のDApps側である報酬システムに受信者が誘導される。
  3. 報酬の選択

    • 受信者は、報酬システムで報酬の種類・内容・金額を選択する。
  4. 報酬の送信

    • 選択された報酬は、送信者に送られ、データベースに記録される。

データベース設計:

報酬データベース

  • Rewards テーブル
    • id: 報酬ID (Primary Key)
    • recipient: 受信者のID
    • sender: 送信者のID
    • reward_type: 報酬の種類(例:ギフトカード、現金)
    • reward_details: 報酬の詳細(例:ギフトカードの金額)
    • timestamp: 報酬が送信された日時

Pythonプログラム設計:

報酬管理システムのAPIエンドポイント

  • POST /notify_receipt: 愛貨の受領を通知するエンドポイント
  • GET /rewards: 利用可能な報酬のリストを取得するエンドポイント
  • POST /send_reward: 報酬を送信し、データベースに記録するエンドポイント

報酬システムのPythonコード:
from flask import Flask, request, jsonify
from datetime import datetime
import sqlite3

app = Flask(__name__)

# データベース接続関数
def get_db_connection():
    conn = sqlite3.connect('rewards.db')
    conn.row_factory = sqlite3.Row
    return conn

# データベース初期化
def init_db():
    conn = get_db_connection()
    with conn:
        conn.execute('''
            CREATE TABLE IF NOT EXISTS Rewards (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                recipient TEXT NOT NULL,
                sender TEXT NOT NULL,
                reward_type TEXT NOT NULL,
                reward_details TEXT NOT NULL,
                timestamp TEXT NOT NULL
            )
        ''')
    conn.close()

# 初期化
init_db()

@app.route('/notify_receipt', methods=['POST'])
def notify_receipt():
    data = request.json
    recipient = data['recipient']
    sender = data['sender']

    # 通知を処理して報酬システムに誘導(実際の誘導はフロントエンドで実装)
    return jsonify({"message": "Receipt notified. Proceed to reward selection."})

@app.route('/rewards', methods=['GET'])
def get_rewards():
    rewards = [
        {"type": "Gift Card", "details": "$10 Gift Card"},
        {"type": "Cash", "details": "$10"},
        {"type": "Coupon", "details": "10% Off Coupon"}
    ]
    return jsonify(rewards)

@app.route('/send_reward', methods=['POST'])
def send_reward():
    data = request.json
    recipient = data['recipient']
    sender = data['sender']
    reward_type = data['reward_type']
    reward_details = data['reward_details']
    timestamp = datetime.utcnow().isoformat()

    conn = get_db_connection()
    with conn:
        conn.execute('''
            INSERT INTO Rewards (recipient, sender, reward_type, reward_details, timestamp)
            VALUES (?, ?, ?, ?, ?)
        ''', (recipient, sender, reward_type, reward_details, timestamp))

    return jsonify({"message": "Reward sent and recorded successfully."})

if __name__ == '__main__':
    app.run(debug=True)
 

DApps側のインターフェース:

DApps側のインターフェースは、ユーザーが愛貨を受領した後に報酬システムへ誘導するUIを持ち、報酬を選択して送信するためのAPIを呼び出す。
async function notifyReceipt(recipient, sender) {
    const response = await fetch('/notify_receipt', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ recipient, sender })
    });
    const result = await response.json();
    alert(result.message);
}

async function getRewards() {
    const response = await fetch('/rewards');
    const rewards = await response.json();
    // 報酬のリストをUIに表示するロジックを追加
}

async function sendReward(recipient, sender, rewardType, rewardDetails) {
    const response = await fetch('/send_reward', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ recipient, sender, reward_type: rewardType, reward_details: rewardDetails })
    });
    const result = await response.json();
    alert(result.message);
}

// 愛貨受領後に呼び出される関数
async function onLoveTokenReceived(recipient, sender) {
    await notifyReceipt(recipient, sender);
    const rewards = await getRewards();
    // ユーザーが報酬を選択するロジックを追加
    // 例えば、ユーザーがギフトカードを選択した場合
    await sendReward(recipient, sender, "Gift Card", "$10 Gift Card");
}
 

これにより、愛貨の受領後に報酬が送信され、データベースに記録される流れが実現される。


2. 月次・年次で愛の行動集計時のフィードバックと報酬 について

じゃあ、もうひとつ別のDAppsについても見ていこう。 

今度は、月次・年次で愛の行動を集計していき、企業から目標達成時に、報酬としてモノやお金が貰えるというものだ。まず、企業と個人を区別するところから始まる。デフォルトで市町村に申請してある各次元の各生命体について、デフォルトでフラグを設定しておく。オープンフラグならプライベート、クローズフラグなら企業に属した生命体、という意味のフラグだ。各次元の各生命体ごとにフラグは設定して貰っておく。そして、いざ、愛の行動をした際に、その次元のその生命体を選択して愛貨をやりとりする場合、オープンなのかクローズなのかでフラッグを読み取る。クローズフラッグのみの行動を月次・年次で集計すれば企業での愛の行動が集計できると言う具合だ。これにより、企業は報酬をあたえたい。そんなDApps側であるPythonプログラムを設計してみよう。

 

1. データベース設計

データベーステーブル:

  • Actions テーブル

    • id: アクションID (Primary Key)
    • dimension: 次元
    • entity: 生命体
    • action_type: アクションの種類
    • timestamp: アクションが行われた日時
    • flag: フラグ(オープン/クローズ)
    • user_id: ユーザーID
  • Rewards テーブル

    • id: 報酬ID (Primary Key)
    • user_id: ユーザーID
    • reward_type: 報酬の種類(例:ギフトカード、現金)
    • reward_details: 報酬の詳細(例:ギフトカードの金額)
    • timestamp: 報酬が送信された日時

2. Pythonプログラム設計

APIエンドポイント

  • POST /record_action: 愛の行動を記録するエンドポイント
  • GET /monthly_summary: 月次の愛の行動を集計するエンドポイント
  • GET /yearly_summary: 年次の愛の行動を集計するエンドポイント
  • POST /distribute_reward: 報酬を送信し、データベースに記録するエンドポイント

報酬管理システムのPythonコード:
from flask import Flask, request, jsonify
from datetime import datetime, timedelta
import sqlite3

app = Flask(__name__)

# データベース接続関数
def get_db_connection():
    conn = sqlite3.connect('actions_rewards.db')
    conn.row_factory = sqlite3.Row
    return conn

# データベース初期化
def init_db():
    conn = get_db_connection()
    with conn:
        conn.execute('''
            CREATE TABLE IF NOT EXISTS Actions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                dimension TEXT NOT NULL,
                entity TEXT NOT NULL,
                action_type TEXT NOT NULL,
                timestamp TEXT NOT NULL,
                flag TEXT NOT NULL,
                user_id TEXT NOT NULL
            )
        ''')
        conn.execute('''
            CREATE TABLE IF NOT EXISTS Rewards (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id TEXT NOT NULL,
                reward_type TEXT NOT NULL,
                reward_details TEXT NOT NULL,
                timestamp TEXT NOT NULL
            )
        ''')
    conn.close()

# 初期化
init_db()

@app.route('/record_action', methods=['POST'])
def record_action():
    data = request.json
    dimension = data['dimension']
    entity = data['entity']
    action_type = data['action_type']
    flag = data['flag']
    user_id = data['user_id']
    timestamp = datetime.utcnow().isoformat()

    conn = get_db_connection()
    with conn:
        conn.execute('''
            INSERT INTO Actions (dimension, entity, action_type, timestamp, flag, user_id)
            VALUES (?, ?, ?, ?, ?, ?)
        ''', (dimension, entity, action_type, timestamp, flag, user_id))

    return jsonify({"message": "Action recorded successfully."})

@app.route('/monthly_summary', methods=['GET'])
def monthly_summary():
    user_id = request.args.get('user_id')
    current_time = datetime.utcnow()
    first_day_of_month = current_time.replace(day=1)
    
    conn = get_db_connection()
    actions = conn.execute('''
        SELECT * FROM Actions
        WHERE user_id = ? AND timestamp >= ? AND flag = 'クローズ'
    ''', (user_id, first_day_of_month.isoformat())).fetchall()

    summary = {"total_actions": len(actions), "actions": [dict(action) for action in actions]}
    return jsonify(summary)

@app.route('/yearly_summary', methods=['GET'])
def yearly_summary():
    user_id = request.args.get('user_id')
    current_time = datetime.utcnow()
    first_day_of_year = current_time.replace(month=1, day=1)

    conn = get_db_connection()
    actions = conn.execute('''
        SELECT * FROM Actions
        WHERE user_id = ? AND timestamp >= ? AND flag = 'クローズ'
    ''', (user_id, first_day_of_year.isoformat())).fetchall()

    summary = {"total_actions": len(actions), "actions": [dict(action) for action in actions]}
    return jsonify(summary)

@app.route('/distribute_reward', methods=['POST'])
def distribute_reward():
    data = request.json
    user_id = data['user_id']
    reward_type = data['reward_type']
    reward_details = data['reward_details']
    timestamp = datetime.utcnow().isoformat()

    conn = get_db_connection()
    with conn:
        conn.execute('''
            INSERT INTO Rewards (user_id, reward_type, reward_details, timestamp)
            VALUES (?, ?, ?, ?)
        ''', (user_id, reward_type, reward_details, timestamp))

    return jsonify({"message": "Reward distributed successfully."})

if __name__ == '__main__':
    app.run(debug=True)
 

3. DApps側のインターフェース

DApps側のインターフェースは、ユーザーが行動を記録し、月次・年次のサマリーを取得し、目標達成時に報酬を受け取るUIを持つ。
async function recordAction(dimension, entity, actionType, flag, userId) {
    const response = await fetch('/record_action', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ dimension, entity, action_type: actionType, flag, user_id: userId })
    });
    const result = await response.json();
    alert(result.message);
}

async function getMonthlySummary(userId) {
    const response = await fetch(`/monthly_summary?user_id=${userId}`);
    const summary = await response.json();
    // 月次サマリーをUIに表示するロジックを追加
}

async function getYearlySummary(userId) {
    const response = await fetch(`/yearly_summary?user_id=${userId}`);
    const summary = await response.json();
    // 年次サマリーをUIに表示するロジックを追加
}

async function distributeReward(userId, rewardType, rewardDetails) {
    const response = await fetch('/distribute_reward', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ user_id: userId, reward_type: rewardType, reward_details: rewardDetails })
    });
    const result = await response.json();
    alert(result.message);
}

// ユーザーが目標達成時に呼び出される関数
async function onGoalAchieved(userId) {
    const rewardType = "Gift Card";
    const rewardDetails = "$10 Gift Card";
    await distributeReward(userId, rewardType, rewardDetails);
}

これにより、ユーザーは月次・年次で愛の行動を集計し、目標達成時に報酬を受け取ることができるDAppsが実現される。

 

いかがであろうか、今回はフィードバックと報酬について記載した。このようにしていけば、報酬を別管理できる。この報酬が後々に重要になってくるのだから。しっかりと設計していきたい。