Files
keinasystem/backend/apps/mail/serializers.py
Akira 04b1ca1bb9 実装完了
Backend(Django)
backend/apps/mail/serializers.py

MailEmailListSerializer を新規追加(フロントエンド向けメール一覧用)
feedback_token フィールドを含む(フィードバックリンク表示用)
backend/apps/mail/views.py

MailEmailCreateView → MailEmailView に変更(GET+POST を統合)
GET /api/mail/emails/ : JWT認証でメール履歴取得(最新100件、account/verdict フィルター対応)
POST /api/mail/emails/ : APIキー認証でWindmillからのメール記録(既存動作を維持)
get_permissions() でメソッドごとに認証方法を切替
MailStatsView を新規追加
GET /api/mail/stats/ : 今日の処理件数、LINE通知数、フィードバック待ち、ルール数を返す
backend/apps/mail/urls.py

emails/ → MailEmailView(GET+POST)
stats/ → MailStatsView を追加
Frontend(Next.js)
frontend/src/app/mail/history/page.tsx (新規作成)

メール処理履歴の一覧テーブル
アカウント・LLM判定でフィルタリング可能
LLM判定・フィードバック状態をバッジで表示
フィードバックトークンがあれば「回答」リンクを表示
frontend/src/app/dashboard/page.tsx (再設計)

2カラムのモジュールカード形式に変更
作付け計画カード: 年度セレクタ、集計数値、作物別集計、クイックアクセス
メール通知カード: 今日の処理件数、LINE通知数、フィードバック待ち、ルール数、メール履歴・ルール管理ボタン
2026-02-22 15:01:50 +09:00

61 lines
2.0 KiB
Python

from rest_framework import serializers
from .models import MailSender, MailEmail
class MailSenderSerializer(serializers.ModelSerializer):
type = serializers.SerializerMethodField()
class Meta:
model = MailSender
fields = ['id', 'type', 'email', 'domain', 'rule', 'note', 'created_at']
def get_type(self, obj):
return 'address' if obj.email else 'domain'
def validate(self, data):
email = data.get('email')
domain = data.get('domain')
if not email and not domain:
raise serializers.ValidationError("email または domain のどちらかを指定してください")
if email and domain:
raise serializers.ValidationError("email と domain を同時に指定することはできません")
return data
class MailEmailCreateSerializer(serializers.ModelSerializer):
"""Windmill からの POST 用"""
class Meta:
model = MailEmail
fields = [
'account', 'message_id', 'sender_email', 'sender_domain',
'subject', 'body_preview', 'received_at', 'llm_verdict'
]
class MailEmailListSerializer(serializers.ModelSerializer):
"""フロントエンド向けメール一覧用"""
feedback_token = serializers.SerializerMethodField()
class Meta:
model = MailEmail
fields = [
'id', 'account', 'sender_email', 'sender_domain',
'subject', 'received_at', 'llm_verdict',
'notified_at', 'feedback', 'feedback_at', 'feedback_token',
]
def get_feedback_token(self, obj):
if hasattr(obj, 'notification_token'):
return str(obj.notification_token.token)
return None
class FeedbackDetailSerializer(serializers.ModelSerializer):
"""フィードバックページ表示用"""
class Meta:
model = MailEmail
fields = [
'id', 'sender_email', 'sender_domain', 'subject',
'body_preview', 'received_at', 'feedback'
]