合并JWL,WZY,TRM代码

Change-Id: Ifb4fcad3c06733e1e005e7d8d9403e3561010fb4
diff --git a/Merge/back_wzy/__pycache__/app.cpython-312.pyc b/Merge/back_wzy/__pycache__/app.cpython-312.pyc
new file mode 100644
index 0000000..215bc7f
--- /dev/null
+++ b/Merge/back_wzy/__pycache__/app.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/__pycache__/config.cpython-310.pyc b/Merge/back_wzy/__pycache__/config.cpython-310.pyc
new file mode 100644
index 0000000..0d915b2
--- /dev/null
+++ b/Merge/back_wzy/__pycache__/config.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/__pycache__/config.cpython-312.pyc b/Merge/back_wzy/__pycache__/config.cpython-312.pyc
new file mode 100644
index 0000000..4e1a3be
--- /dev/null
+++ b/Merge/back_wzy/__pycache__/config.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/__pycache__/extensions.cpython-310.pyc b/Merge/back_wzy/__pycache__/extensions.cpython-310.pyc
new file mode 100644
index 0000000..ba72eec
--- /dev/null
+++ b/Merge/back_wzy/__pycache__/extensions.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/__pycache__/extensions.cpython-312.pyc b/Merge/back_wzy/__pycache__/extensions.cpython-312.pyc
new file mode 100644
index 0000000..27ba8c2
--- /dev/null
+++ b/Merge/back_wzy/__pycache__/extensions.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/all_tables.sql b/Merge/back_wzy/all_tables.sql
new file mode 100644
index 0000000..fd5d1e5
--- /dev/null
+++ b/Merge/back_wzy/all_tables.sql
@@ -0,0 +1,182 @@
+/*
+数据库设计说明:
+1.	核心表结构:
+	users:存储用户信息,包含角色管理和账号状态
+	posts:核心内容表,支持多模态内容(图文/视频/文档)
+	behaviors:记录用户互动行为(点赞/收藏/浏览等)
+	comments:评论系统,支持多级回复
+	follows:用户社交关系
+2.	推荐系统支持:
+	posts.heat 字段存储动态计算的热度值
+	behaviors 表记录用户行为用于协同过滤
+	user_tags 表构建用户兴趣画像
+	通过 post_tags 实现内容标签分类
+3.	多模态内容处理:
+	posts.media_urls 使用 JSON 类型存储多个资源 URL
+	posts.type 区分不同类型的内容(图文/视频/文档)
+4.	审核与安全:
+	audits 表记录内容审核历史
+	posts.status 管理内容生命周期状态
+	logs 表记录系统操作和访问日志
+5.	性能优化:
+	为查询频繁字段添加索引(热度/行为类型/时间)
+	使用 JSON 类型存储灵活数据(通知内容/媒体资源)
+	通过 heat 字段预计算支持热门排序
+6.	扩展性设计:
+	用户画像系统通过 user_tags 表实现
+	通知系统支持多种互动类型
+	行为表设计支持未来扩展新行为类型
+*/
+
+DROP DATABASE IF EXISTS redbook;
+
+-- 创建数据库
+CREATE DATABASE IF NOT EXISTS redbook DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
+USE redbook;
+
+-- 用户表
+CREATE TABLE users (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',
+    username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
+    password VARCHAR(255) NOT NULL COMMENT '加密密码',
+    email VARCHAR(100) NOT NULL UNIQUE COMMENT '邮箱',
+    avatar VARCHAR(255) COMMENT '头像URL',
+    role ENUM('user', 'admin') DEFAULT 'user' COMMENT '角色',
+    bio VARCHAR(255) COMMENT '个人简介',
+    status ENUM('active', 'banned', 'muted') DEFAULT 'active' COMMENT '账号状态',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE=InnoDB COMMENT='用户表';
+
+-- 标签表
+CREATE TABLE tags (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '标签ID',
+    name VARCHAR(50) NOT NULL UNIQUE COMMENT '标签名称',
+    description VARCHAR(255) COMMENT '标签描述',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
+) ENGINE=InnoDB COMMENT='内容标签表';
+
+-- 话题/超话表
+CREATE TABLE topics (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '话题ID',
+    name VARCHAR(100) NOT NULL UNIQUE COMMENT '话题名称',
+    description TEXT COMMENT '话题描述',
+    status ENUM('active', 'archived') DEFAULT 'active' COMMENT '状态',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
+) ENGINE=InnoDB COMMENT='话题/超话表';
+
+-- 内容帖子表
+CREATE TABLE posts (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '帖子ID',
+    user_id INT NOT NULL COMMENT '作者ID',
+    topic_id INT COMMENT '所属话题ID',
+    type ENUM('text', 'image', 'video', 'document') DEFAULT 'text' COMMENT '内容类型',
+    title VARCHAR(255) NOT NULL COMMENT '标题',
+    content TEXT NOT NULL COMMENT '正文内容',
+    media_urls JSON COMMENT '媒体资源URL数组',
+    status ENUM('draft', 'pending', 'published', 'deleted', 'rejected') DEFAULT 'draft' COMMENT '状态',
+    heat INT DEFAULT 0 COMMENT '热度值',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
+    FOREIGN KEY (topic_id) REFERENCES topics(id) ON DELETE SET NULL
+) ENGINE=InnoDB COMMENT='内容帖子表';
+
+-- 帖子标签关联表
+CREATE TABLE post_tags (
+    post_id INT NOT NULL COMMENT '帖子ID',
+    tag_id INT NOT NULL COMMENT '标签ID',
+    PRIMARY KEY (post_id, tag_id),
+    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
+    FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='帖子标签关联表';
+
+-- 用户行为表
+CREATE TABLE behaviors (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '行为ID',
+    user_id INT NOT NULL COMMENT '用户ID',
+    post_id INT NOT NULL COMMENT '帖子ID',
+    type ENUM('like', 'comment', 'favorite', 'view', 'share') NOT NULL COMMENT '行为类型',
+    value INT DEFAULT 1 COMMENT '行为值',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '行为时间',
+    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
+    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='用户行为记录表';
+
+-- 评论表
+CREATE TABLE comments (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '评论ID',
+    post_id INT NOT NULL COMMENT '帖子ID',
+    user_id INT NOT NULL COMMENT '用户ID',
+    parent_id INT DEFAULT NULL COMMENT '父评论ID',
+    content TEXT NOT NULL COMMENT '评论内容',
+    status ENUM('active', 'deleted') DEFAULT 'active' COMMENT '状态',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
+    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
+    FOREIGN KEY (parent_id) REFERENCES comments(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='评论表';
+
+-- 用户关注关系表
+CREATE TABLE follows (
+    follower_id INT NOT NULL COMMENT '关注者ID',
+    followee_id INT NOT NULL COMMENT '被关注者ID',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '关注时间',
+    PRIMARY KEY (follower_id, followee_id),
+    FOREIGN KEY (follower_id) REFERENCES users(id) ON DELETE CASCADE,
+    FOREIGN KEY (followee_id) REFERENCES users(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='用户关注关系表';
+
+-- 通知表
+CREATE TABLE notifications (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '通知ID',
+    user_id INT NOT NULL COMMENT '接收用户ID',
+    type ENUM('like', 'comment', 'follow', 'system', 'audit') NOT NULL COMMENT '通知类型',
+    content JSON NOT NULL COMMENT '通知内容',
+    is_read BOOLEAN DEFAULT FALSE COMMENT '是否已读',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='用户通知表';
+
+-- 审核记录表
+CREATE TABLE audits (
+    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '审核ID',
+    post_id INT NOT NULL COMMENT '帖子ID',
+    admin_id INT NOT NULL COMMENT '管理员ID',
+    result ENUM('approved', 'rejected') NOT NULL COMMENT '审核结果',
+    reason VARCHAR(255) COMMENT '审核原因',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '审核时间',
+    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
+    FOREIGN KEY (admin_id) REFERENCES users(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='内容审核记录表';
+
+-- 日志表
+CREATE TABLE logs (
+    id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '日志ID',
+    user_id INT DEFAULT NULL COMMENT '用户ID',
+    type ENUM('access', 'error', 'behavior', 'system') NOT NULL COMMENT '日志类型',
+    content TEXT NOT NULL COMMENT '日志内容',
+    ip VARCHAR(45) COMMENT 'IP地址',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '记录时间',
+    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
+) ENGINE=InnoDB COMMENT='系统日志表';
+
+-- 用户兴趣标签表(用户画像)
+CREATE TABLE user_tags (
+    user_id INT NOT NULL COMMENT '用户ID',
+    tag_id INT NOT NULL COMMENT '标签ID',
+    weight FLOAT DEFAULT 1.0 COMMENT '兴趣权重',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    PRIMARY KEY (user_id, tag_id),
+    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
+    FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
+) ENGINE=InnoDB COMMENT='用户兴趣标签表';
+
+-- 索引优化
+CREATE INDEX idx_posts_heat ON posts(heat);
+CREATE INDEX idx_behaviors_type ON behaviors(type);
+CREATE INDEX idx_notifications_read ON notifications(is_read);
+CREATE INDEX idx_logs_created ON logs(created_at);
+CREATE INDEX idx_comments_post ON comments(post_id);
\ No newline at end of file
diff --git a/Merge/back_wzy/app.py b/Merge/back_wzy/app.py
new file mode 100644
index 0000000..a90f62f
--- /dev/null
+++ b/Merge/back_wzy/app.py
@@ -0,0 +1,30 @@
+# app.py
+
+from flask import Flask
+from flask_cors import CORS
+from config import Config
+from extensions import db, migrate
+
+def create_app():
+    app = Flask(__name__)
+    app.config.from_object(Config)
+
+    # 启用 CORS:允许前端 http://localhost:5173 发起跨域请求
+    # 生产环境请根据实际域名调整 origins
+    CORS(app, resources={r"/*": {"origins": "*"}})
+    db.init_app(app)
+    migrate.init_app(app, db)
+
+    # 在工厂函数里再导入并注册蓝图
+    from routes.posts    import posts_bp
+    from routes.comments import comments_bp
+
+    app.register_blueprint(posts_bp,    url_prefix='/posts')
+    app.register_blueprint(comments_bp, url_prefix='/posts/<int:post_id>/comments')
+
+    return app
+
+# 只有直接用 python app.py 时,这段才会执行
+if __name__ == '__main__':
+    app = create_app()
+    app.run(host='0.0.0.0', port=5714, debug=True)
diff --git a/Merge/back_wzy/config.py b/Merge/back_wzy/config.py
new file mode 100644
index 0000000..e5bdb32
--- /dev/null
+++ b/Merge/back_wzy/config.py
@@ -0,0 +1,11 @@
+# config.py
+import os
+
+basedir = os.path.abspath(os.path.dirname(__file__))
+
+class Config:
+    SECRET_KEY = os.environ.get('SECRET_KEY', 'you-will-never-guess')
+    SQLALCHEMY_DATABASE_URI = os.environ.get(
+        'SQLURL'
+    )
+    SQLALCHEMY_TRACK_MODIFICATIONS = False
diff --git a/Merge/back_wzy/extensions.py b/Merge/back_wzy/extensions.py
new file mode 100644
index 0000000..3563787
--- /dev/null
+++ b/Merge/back_wzy/extensions.py
@@ -0,0 +1,6 @@
+# extensions.py(根目录,同级于 app.py)
+from flask_sqlalchemy import SQLAlchemy
+from flask_migrate    import Migrate
+
+db      = SQLAlchemy()
+migrate = Migrate()
diff --git a/Merge/back_wzy/manage.py b/Merge/back_wzy/manage.py
new file mode 100644
index 0000000..15ab995
--- /dev/null
+++ b/Merge/back_wzy/manage.py
@@ -0,0 +1,12 @@
+# manage.py
+from flask_script import Manager
+from flask_migrate import MigrateCommand
+
+from app import app, db
+
+manager = Manager(app)
+# 添加 db 子命令: migrate, upgrade, downgrade 等
+manager.add_command('db', MigrateCommand)
+
+if __name__ == '__main__':
+    manager.run()
diff --git a/Merge/back_wzy/models/__init__.py b/Merge/back_wzy/models/__init__.py
new file mode 100644
index 0000000..f7cef7b
--- /dev/null
+++ b/Merge/back_wzy/models/__init__.py
@@ -0,0 +1,12 @@
+# models/__init__.py
+# --------------------------------------------------
+# 绝**对**不要**从** app.py 导入 db!
+# 改成:
+from extensions import db
+
+from .user     import User
+from .topic    import Topic
+from .tag      import Tag
+from .post     import Post, post_tags
+from .behavior import Behavior
+from .comment  import Comment
diff --git a/Merge/back_wzy/models/__pycache__/__init__.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..fa2d5c2
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/__init__.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/__init__.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..fe53b2a
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/behavior.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/behavior.cpython-310.pyc
new file mode 100644
index 0000000..bd2fdec
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/behavior.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/behavior.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/behavior.cpython-312.pyc
new file mode 100644
index 0000000..71f3757
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/behavior.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/comment.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/comment.cpython-310.pyc
new file mode 100644
index 0000000..550853e
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/comment.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/comment.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/comment.cpython-312.pyc
new file mode 100644
index 0000000..393c6d3
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/comment.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/post.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/post.cpython-310.pyc
new file mode 100644
index 0000000..3131d0b
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/post.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/post.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/post.cpython-312.pyc
new file mode 100644
index 0000000..1d64737
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/post.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/tag.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/tag.cpython-310.pyc
new file mode 100644
index 0000000..649f51e
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/tag.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/tag.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/tag.cpython-312.pyc
new file mode 100644
index 0000000..d76c0e0
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/tag.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/topic.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/topic.cpython-310.pyc
new file mode 100644
index 0000000..7fd8f9e
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/topic.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/topic.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/topic.cpython-312.pyc
new file mode 100644
index 0000000..a779595
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/topic.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/user.cpython-310.pyc b/Merge/back_wzy/models/__pycache__/user.cpython-310.pyc
new file mode 100644
index 0000000..2fc98eb
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/user.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/__pycache__/user.cpython-312.pyc b/Merge/back_wzy/models/__pycache__/user.cpython-312.pyc
new file mode 100644
index 0000000..e3841c7
--- /dev/null
+++ b/Merge/back_wzy/models/__pycache__/user.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/models/behavior.py b/Merge/back_wzy/models/behavior.py
new file mode 100644
index 0000000..aed413f
--- /dev/null
+++ b/Merge/back_wzy/models/behavior.py
@@ -0,0 +1,13 @@
+# models/behavior.py
+from extensions import db
+from datetime import datetime
+
+class Behavior(db.Model):
+    __tablename__ = 'behaviors'
+
+    id = db.Column(db.BigInteger, primary_key=True)
+    user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
+    post_id = db.Column(db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), nullable=False)
+    type = db.Column(db.Enum('like', 'comment', 'favorite', 'view', 'share'), nullable=False)
+    value = db.Column(db.Integer, default=1, nullable=False)
+    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
diff --git a/Merge/back_wzy/models/comment.py b/Merge/back_wzy/models/comment.py
new file mode 100644
index 0000000..ce25287
--- /dev/null
+++ b/Merge/back_wzy/models/comment.py
@@ -0,0 +1,24 @@
+# models/comment.py
+from extensions import db
+from datetime import datetime
+
+class Comment(db.Model):
+    __tablename__ = 'comments'
+
+    id = db.Column(db.Integer, primary_key=True)
+    post_id = db.Column(db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), nullable=False)
+    user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
+    parent_id = db.Column(db.Integer, db.ForeignKey('comments.id', ondelete='CASCADE'))
+    content = db.Column(db.Text, nullable=False)
+    status = db.Column(db.Enum('active', 'deleted'), default='active', nullable=False)
+    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
+    updated_at = db.Column(db.DateTime, default=datetime.utcnow,
+                           onupdate=datetime.utcnow, nullable=False)
+
+    # self-referential replies
+    replies = db.relationship(
+        'Comment',
+        backref=db.backref('parent', remote_side=[id]),
+        lazy='dynamic',
+        cascade='all, delete-orphan'
+    )
diff --git a/Merge/back_wzy/models/post.py b/Merge/back_wzy/models/post.py
new file mode 100644
index 0000000..ab99191
--- /dev/null
+++ b/Merge/back_wzy/models/post.py
@@ -0,0 +1,32 @@
+# models/post.py
+from extensions import db
+from datetime import datetime
+
+# association table for Post <-> Tag
+post_tags = db.Table(
+    'post_tags',
+    db.Column('post_id', db.Integer, db.ForeignKey('posts.id', ondelete='CASCADE'), primary_key=True),
+    db.Column('tag_id', db.Integer, db.ForeignKey('tags.id', ondelete='CASCADE'), primary_key=True)
+)
+
+class Post(db.Model):
+    __tablename__ = 'posts'
+
+    id = db.Column(db.Integer, primary_key=True)
+    user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
+    topic_id = db.Column(db.Integer, db.ForeignKey('topics.id', ondelete='SET NULL'))
+    type = db.Column(db.Enum('text', 'image', 'video', 'document'), default='text', nullable=False)
+    title = db.Column(db.String(255), nullable=False)
+    content = db.Column(db.Text, nullable=False)
+    media_urls = db.Column(db.JSON)
+    status = db.Column(db.Enum('draft', 'pending', 'published', 'deleted', 'rejected'),
+                       default='draft', nullable=False)
+    heat = db.Column(db.Integer, default=0, nullable=False)
+    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
+    updated_at = db.Column(db.DateTime, default=datetime.utcnow,
+                           onupdate=datetime.utcnow, nullable=False)
+
+    # relationships
+    tags = db.relationship('Tag', secondary=post_tags, backref=db.backref('posts', lazy='dynamic'))
+    behaviors = db.relationship('Behavior', backref='post', lazy='dynamic', cascade='all, delete')
+    comments = db.relationship('Comment', backref='post', lazy='dynamic', cascade='all, delete')
diff --git a/Merge/back_wzy/models/tag.py b/Merge/back_wzy/models/tag.py
new file mode 100644
index 0000000..7753a38
--- /dev/null
+++ b/Merge/back_wzy/models/tag.py
@@ -0,0 +1,13 @@
+# models/tag.py
+from extensions import db
+from datetime import datetime
+
+class Tag(db.Model):
+    __tablename__ = 'tags'
+
+    id = db.Column(db.Integer, primary_key=True)
+    name = db.Column(db.String(50), unique=True, nullable=False)
+    description = db.Column(db.String(255))
+    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
+
+    # posts relationship via association table defined in post.py
diff --git a/Merge/back_wzy/models/topic.py b/Merge/back_wzy/models/topic.py
new file mode 100644
index 0000000..d0e5a2e
--- /dev/null
+++ b/Merge/back_wzy/models/topic.py
@@ -0,0 +1,14 @@
+# models/topic.py
+from extensions import db
+from datetime import datetime
+
+class Topic(db.Model):
+    __tablename__ = 'topics'
+
+    id = db.Column(db.Integer, primary_key=True)
+    name = db.Column(db.String(100), unique=True, nullable=False)
+    description = db.Column(db.Text)
+    status = db.Column(db.Enum('active', 'archived'), default='active', nullable=False)
+    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
+
+    posts = db.relationship('Post', backref='topic', lazy='dynamic', cascade='all, delete')
diff --git a/Merge/back_wzy/models/user.py b/Merge/back_wzy/models/user.py
new file mode 100644
index 0000000..f27e7d3
--- /dev/null
+++ b/Merge/back_wzy/models/user.py
@@ -0,0 +1,68 @@
+# models/user.py
+
+from datetime import datetime
+from extensions import db
+
+# 关联表:用户关注关系
+follows = db.Table(
+    'follows',
+    db.Column('follower_id', db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), primary_key=True),
+    db.Column('followee_id', db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'), primary_key=True),
+    db.Column('created_at', db.DateTime, default=datetime.utcnow, nullable=False)
+)
+
+class User(db.Model):
+    __tablename__ = 'users'
+
+    id = db.Column(db.Integer, primary_key=True)
+    username = db.Column(db.String(50), unique=True, nullable=False)
+    password = db.Column(db.String(255), nullable=False)
+    email = db.Column(db.String(100), unique=True, nullable=False)
+    avatar = db.Column(db.String(255))
+    role = db.Column(db.Enum('user', 'admin'), default='user', nullable=False)
+    bio = db.Column(db.String(255))
+    status = db.Column(db.Enum('active', 'banned', 'muted'), default='active', nullable=False)
+    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
+    updated_at = db.Column(
+        db.DateTime,
+        default=datetime.utcnow,
+        onupdate=datetime.utcnow,
+        nullable=False
+    )
+
+    # 用户发布的帖子
+    posts = db.relationship(
+        'Post',
+        backref='author',
+        lazy='dynamic',
+        cascade='all, delete-orphan'
+    )
+
+    # 用户的互动行为
+    behaviors = db.relationship(
+        'Behavior',
+        backref='user',
+        lazy='dynamic',
+        cascade='all, delete-orphan'
+    )
+
+    # 用户发表的评论
+    comments = db.relationship(
+        'Comment',
+        backref='user',
+        lazy='dynamic',
+        cascade='all, delete-orphan'
+    )
+
+    # 用户关注的对象列表
+    following = db.relationship(
+        'User',
+        secondary=follows,
+        primaryjoin=(id == follows.c.follower_id),
+        secondaryjoin=(id == follows.c.followee_id),
+        backref=db.backref('followers', lazy='dynamic'),
+        lazy='dynamic'
+    )
+
+    def __repr__(self):
+        return f"<User {self.username!r} id={self.id}>"
diff --git a/Merge/back_wzy/readme.md b/Merge/back_wzy/readme.md
new file mode 100644
index 0000000..9fab23e
--- /dev/null
+++ b/Merge/back_wzy/readme.md
@@ -0,0 +1,400 @@
+## 2. 帖子(Post)
+
+### 2.1 发布新帖
+
+```
+POST /posts
+```
+
+- **描述**:创建一条帖子
+
+- **请求头**
+
+  ```
+  Content-Type: application/json
+  ```
+
+- **请求体**
+
+  ```json
+  {
+    "user_id": 1,
+    "topic_id": 1,                    // 可选,必须是已存在 topic 的 ID
+    "title": "帖子标题",
+    "content": "正文内容",
+    "media_urls": [                   // 可选,字符串数组
+      "https://example.com/img1.jpg",
+      "https://example.com/vid1.mp4"
+    ],
+    "status": "published"             // draft|pending|published|deleted|rejected
+  }
+  ```
+
+- **成功响应**
+
+  - **状态**:201 Created
+
+  - **Body**
+
+    ```json
+    { "id": 42 }
+    ```
+
+- **错误**
+
+  - 400 Bad Request: 缺少 user_id、title 或 content
+  - 400 Bad Request: topic_id 不存在
+  - 400 Bad Request: JSON 解析错误
+  - 422 Unprocessable Entity: media_urls 格式错误
+  - 500 Internal Server Error: 外键约束或其他数据库错误
+
+------
+
+### 2.2 获取帖子列表
+
+```
+GET /posts
+```
+
+- **描述**:拉取所有 `status=published` 的帖子
+
+- **响应**
+
+  - **状态**:200 OK
+
+  - **Body**
+
+    ```json
+    [
+      {
+        "id": 42,
+        "title": "帖子标题",
+        "heat": 5,
+        "created_at": "2025-06-12T16:00:00"
+      },
+      ...
+    ]
+    ```
+
+------
+
+### 2.3 查看帖子详情
+
+```
+GET /posts/{post_id}
+```
+
+- **描述**:查看单条帖子完整信息
+
+- **路径参数**
+
+  | 参数    | 描述    |
+  | ------- | ------- |
+  | post_id | 帖子 ID |
+
+- **响应**
+
+  - **状态**:200 OK
+
+  - **Body**
+
+    ```json
+    {
+      "id": 42,
+      "user_id": 1,
+      "topic_id": 1,
+      "title": "帖子标题",
+      "content": "正文内容",
+      "media_urls": ["…"],
+      "status": "published",
+      "heat": 5,
+      "created_at": "2025-06-12T16:00:00",
+      "updated_at": "2025-06-12T16:05:00"
+    }
+    ```
+
+- **错误**
+
+  - 404 Not Found: 帖子不存在
+
+------
+
+### 2.4 修改帖子
+
+```
+PUT /posts/{post_id}
+```
+
+- **描述**:更新帖子字段
+
+- **路径参数**
+
+  | 参数    | 描述    |
+  | ------- | ------- |
+  | post_id | 帖子 ID |
+
+- **请求头**
+
+  ```
+  Content-Type: application/json
+  ```
+
+- **请求体**(所有字段可选,依需更新)
+
+  ```json
+  {
+    "title": "新标题",
+    "content": "新内容",
+    "topic_id": 2,
+    "media_urls": ["…"],
+    "status": "draft"
+  }
+  ```
+
+- **响应**
+
+  - **状态**:204 No Content
+
+- **错误**
+
+  - 400 Bad Request: JSON 格式或字段值不合法
+  - 404 Not Found: 帖子不存在
+
+------
+
+### 2.5 删除帖子
+
+```
+DELETE /posts/{post_id}
+```
+
+- **描述**:删除帖子及其关联行为、评论
+
+- **路径参数**
+
+  | 参数    | 描述    |
+  | ------- | ------- |
+  | post_id | 帖子 ID |
+
+- **响应**
+
+  - **状态**:204 No Content
+
+- **错误**
+
+  - 404 Not Found: 帖子不存在
+
+------
+
+## 3. 互动行为(Behavior)
+
+> 支持四种操作:`like`、`favorite`、`view`、`share`。其中 `like` 和 `favorite` 限制每人每帖最多一次,可撤销;`view`/`share` 不限次数,不提供撤销。
+
+### 3.1 点赞
+
+```
+POST /posts/{post_id}/like
+```
+
+- **描述**:用户点赞,热度 +1
+
+- **请求头**
+
+  ```
+  Content-Type: application/json
+  ```
+
+- **请求体**
+
+  ```json
+  { "user_id": 1 }
+  ```
+
+- **响应**
+
+  - **状态**:201 Created
+
+- **错误**
+
+  - 400 Bad Request: 已点赞过 → `{"error":"already liked"}`
+  - 400 Bad Request: 缺少 user_id
+  - 404 Not Found: 帖子或用户不存在
+
+### 3.2 取消点赞
+
+```
+DELETE /posts/{post_id}/like
+```
+
+- **描述**:撤销点赞,热度 -1(底线 0)
+
+- **请求头**
+
+  ```
+  Content-Type: application/json
+  ```
+
+- **请求体**
+
+  ```json
+  { "user_id": 1 }
+  ```
+
+- **响应**
+
+  - **状态**:204 No Content
+
+- **错误**
+
+  - 400 Bad Request: 未点赞过 → `{"error":"not liked yet"}`
+  - 404 Not Found: 帖子或用户不存在
+
+------
+
+### 3.3 收藏
+
+```
+POST /posts/{post_id}/favorite
+```
+
+- **描述**:用户收藏,热度 +1
+- **请求头/体/响应/错误**
+   与点赞接口完全一致,只把 `like` 换成 `favorite`,错误信息为 `already favorited` / `not favorited yet`。
+
+### 3.4 取消收藏
+
+```
+DELETE /posts/{post_id}/favorite
+```
+
+- **描述**:撤销收藏,热度 -1
+- **请求头/体/响应/错误**
+   同上。
+
+------
+
+### 3.5 浏览
+
+```
+POST /posts/{post_id}/view
+```
+
+- **描述**:记录一次浏览,热度 +1
+
+- **请求体**
+
+  ```json
+  { "user_id": 1 }
+  ```
+
+- **响应**
+
+  - 201 Created
+
+不支持撤销;不做去重检查。
+
+------
+
+### 3.6 分享
+
+```
+POST /posts/{post_id}/share
+```
+
+- **描述**:记录一次分享,热度 +1
+- **请求体/响应**
+   同浏览。
+
+------
+
+## 4. 评论(Comment)
+
+### 4.1 添加评论
+
+```
+POST /posts/{post_id}/comments
+```
+
+- **描述**:为帖子添加评论或回复
+
+- **请求头**
+
+  ```
+  Content-Type: application/json
+  ```
+
+- **请求体**
+
+  ```json
+  {
+    "user_id": 2,
+    "content": "这是评论内容",
+    "parent_id": 1    // 可选:回复某条评论时填,一级评论则省略
+  }
+  ```
+
+- **响应**
+
+  - **状态**:201 Created
+
+  - **Body**
+
+    ```json
+    { "id": 7 }
+    ```
+
+- **错误**
+
+  - 400 Bad Request: 缺少 user_id 或 content
+  - 404 Not Found: 帖子或 parent_id 不存在
+
+------
+
+### 4.2 获取评论列表
+
+```
+GET /posts/{post_id}/comments
+```
+
+- **描述**:拉取该帖所有一级评论及其完整回复树
+
+- **响应**
+
+  - **状态**:200 OK
+
+  - **Body**
+
+    ```json
+    [
+      {
+        "id": 1,
+        "user_id": 1,
+        "content": "一级评论",
+        "created_at": "…",
+        "replies": [
+          {
+            "id": 2,
+            "user_id": 2,
+            "content": "回复评论",
+            "created_at": "…",
+            "replies": [ … ]
+          }
+        ]
+      },
+      …
+    ]
+    ```
+
+- **错误**
+
+  - 404 Not Found: 帖子不存在
+
+------
+
+> **通用错误响应格式**
+>
+> ```json
+> {
+>   "error": "描述信息"
+> }
+> ```
\ No newline at end of file
diff --git a/Merge/back_wzy/requirements.txt b/Merge/back_wzy/requirements.txt
new file mode 100644
index 0000000..4db9d23
--- /dev/null
+++ b/Merge/back_wzy/requirements.txt
@@ -0,0 +1,6 @@
+# requirements.txt
+Flask>=2.0
+Flask-SQLAlchemy>=2.5
+Flask-Migrate>=3.1
+Flask-Script>=2.0
+PyMySQL>=1.0
diff --git a/Merge/back_wzy/routes/__init__.py b/Merge/back_wzy/routes/__init__.py
new file mode 100644
index 0000000..5410dd3
--- /dev/null
+++ b/Merge/back_wzy/routes/__init__.py
@@ -0,0 +1,4 @@
+# routes/__init__.py
+from flask import Blueprint
+
+# 可以在这里统一注册蓝图,也可以直接在 app.py 中 import
diff --git a/Merge/back_wzy/routes/__pycache__/__init__.cpython-310.pyc b/Merge/back_wzy/routes/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..fd9f45b
--- /dev/null
+++ b/Merge/back_wzy/routes/__pycache__/__init__.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/routes/__pycache__/__init__.cpython-312.pyc b/Merge/back_wzy/routes/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..acde7ed
--- /dev/null
+++ b/Merge/back_wzy/routes/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/routes/__pycache__/comments.cpython-310.pyc b/Merge/back_wzy/routes/__pycache__/comments.cpython-310.pyc
new file mode 100644
index 0000000..087a126
--- /dev/null
+++ b/Merge/back_wzy/routes/__pycache__/comments.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/routes/__pycache__/comments.cpython-312.pyc b/Merge/back_wzy/routes/__pycache__/comments.cpython-312.pyc
new file mode 100644
index 0000000..4bd83ee
--- /dev/null
+++ b/Merge/back_wzy/routes/__pycache__/comments.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/routes/__pycache__/posts.cpython-310.pyc b/Merge/back_wzy/routes/__pycache__/posts.cpython-310.pyc
new file mode 100644
index 0000000..a22b03e
--- /dev/null
+++ b/Merge/back_wzy/routes/__pycache__/posts.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_wzy/routes/__pycache__/posts.cpython-312.pyc b/Merge/back_wzy/routes/__pycache__/posts.cpython-312.pyc
new file mode 100644
index 0000000..a957747
--- /dev/null
+++ b/Merge/back_wzy/routes/__pycache__/posts.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_wzy/routes/comments.py b/Merge/back_wzy/routes/comments.py
new file mode 100644
index 0000000..2d5b654
--- /dev/null
+++ b/Merge/back_wzy/routes/comments.py
@@ -0,0 +1,46 @@
+# routes/comments.py
+from flask import Blueprint, request, jsonify, abort
+from extensions      import db
+from models.comment  import Comment
+from models.behavior import Behavior
+
+comments_bp = Blueprint('comments', __name__)
+
+@comments_bp.route('', methods=['POST'])
+def add_comment(post_id):
+    data = request.get_json() or {}
+    user_id = data.get('user_id')
+    content = data.get('content')
+    if not user_id or not content:
+        return jsonify({'error': 'user_id and content required'}), 400
+
+    comment = Comment(
+        post_id=post_id,
+        user_id=user_id,
+        content=content,
+        parent_id=data.get('parent_id')
+    )
+    db.session.add(comment)
+    # 记录行为
+    beh = Behavior(user_id=user_id, post_id=post_id, type='comment')
+    db.session.add(beh)
+    db.session.commit()
+    return jsonify({'id': comment.id}), 201
+
+@comments_bp.route('', methods=['GET'])
+def list_comments(post_id):
+    def serialize(c):
+        return {
+            'id': c.id,
+            'user_id': c.user_id,
+            'content': c.content,
+            'created_at': c.created_at.isoformat(),
+            'replies': [serialize(r) for r in c.replies]
+        }
+
+    comments = Comment.query.filter_by(
+        post_id=post_id,
+        status='active',
+        parent_id=None
+    ).order_by(Comment.created_at.asc()).all()
+    return jsonify([serialize(c) for c in comments])
diff --git a/Merge/back_wzy/routes/posts.py b/Merge/back_wzy/routes/posts.py
new file mode 100644
index 0000000..e01bdd8
--- /dev/null
+++ b/Merge/back_wzy/routes/posts.py
@@ -0,0 +1,150 @@
+# routes/posts.py
+from flask import Blueprint, request, jsonify, abort
+from extensions    import db
+from models.post   import Post
+from models.behavior import Behavior
+
+posts_bp = Blueprint('posts', __name__)
+
+@posts_bp.route('', methods=['POST'])
+def create_post():
+    data = request.get_json() or {}
+    post = Post(**data)
+    db.session.add(post)
+    db.session.commit()
+    return jsonify({'id': post.id}), 201
+
+@posts_bp.route('', methods=['GET'])
+def list_posts():
+    posts = Post.query.filter_by(status='published').all()
+    return jsonify([{
+        'id': p.id,
+        'title': p.title,
+        'heat': p.heat,
+        'created_at': p.created_at.isoformat()
+    } for p in posts])
+
+@posts_bp.route('/<int:post_id>', methods=['GET'])
+def get_post(post_id):
+    post = Post.query.get_or_404(post_id)
+    return jsonify({
+        'id': post.id,
+        'user_id': post.user_id,
+        'title': post.title,
+        'content': post.content,
+        'media_urls': post.media_urls,
+        'status': post.status,
+        'heat': post.heat,
+        'created_at': post.created_at.isoformat(),
+        'updated_at': post.updated_at.isoformat()
+    })
+
+@posts_bp.route('/<int:post_id>', methods=['PUT'])
+def update_post(post_id):
+    """
+    修改帖子
+    URL 参数:
+      post_id - 要修改的帖子 ID
+    JSON Body 可选字段:
+      title       (string)
+      content     (string)
+      topic_id    (int)     — 必须是 topics 表中已有的 ID
+      media_urls  (list)    — 字符串数组
+      status      (string)  — 'draft','pending','published','deleted','rejected'
+    """
+    post = Post.query.get_or_404(post_id)
+    data = request.get_json() or {}
+    # 只更新客户端传来的字段
+    for key in ('title','content','topic_id','media_urls','status'):
+        if key in data:
+            setattr(post, key, data[key])
+    db.session.commit()
+    return '', 204
+
+@posts_bp.route('/<int:post_id>', methods=['DELETE'])
+def delete_post(post_id):
+    post = Post.query.get_or_404(post_id)
+    db.session.delete(post)
+    db.session.commit()
+    return '', 204
+
+
+@posts_bp.route('/<int:post_id>/<action>', methods=['POST'])
+def post_action(post_id, action):
+    """
+    支持的 action: like, favorite, view, share
+    对于 like 和 favorite,保证每个用户每帖只做一次。
+    """
+    if action not in ('like', 'favorite', 'view', 'share'):
+        abort(400, 'Invalid action')
+
+    data = request.get_json() or {}
+    user_id = data.get('user_id')
+    if not user_id:
+        abort(400, 'user_id required')
+
+    # 对 like/favorite 做去重检查
+    if action in ('like', 'favorite'):
+        exists = Behavior.query.filter_by(
+            user_id=user_id,
+            post_id=post_id,
+            type=action
+        ).first()
+        if exists:
+            return jsonify({'error': f'already {action}d'}), 400
+
+    # 创建行为记录
+    beh = Behavior(user_id=user_id, post_id=post_id, type=action)
+    db.session.add(beh)
+
+    # 更新热度
+    post = Post.query.get_or_404(post_id)
+    post.heat += 1
+
+    db.session.commit()
+    return '', 201
+
+
+# 取消点赞
+@posts_bp.route('/<int:post_id>/like', methods=['DELETE'])
+def unlike(post_id):
+    user_id = request.get_json(silent=True) and request.get_json().get('user_id')
+    if not user_id:
+        abort(400, 'user_id required')
+    # 查找已有的 like 行为
+    beh = Behavior.query.filter_by(
+        user_id=user_id,
+        post_id=post_id,
+        type='like'
+    ).first()
+    if not beh:
+        return jsonify({'error': 'not liked yet'}), 400
+
+    db.session.delete(beh)
+    # 更新热度,确保不降到负数
+    post = Post.query.get_or_404(post_id)
+    post.heat = max(post.heat - 1, 0)
+    db.session.commit()
+    return '', 204
+
+# 取消收藏
+@posts_bp.route('/<int:post_id>/favorite', methods=['DELETE'])
+def unfavorite(post_id):
+    user_id = request.get_json(silent=True) and request.get_json().get('user_id')
+    if not user_id:
+        abort(400, 'user_id required')
+    # 查找已有的 favorite 行为
+    beh = Behavior.query.filter_by(
+        user_id=user_id,
+        post_id=post_id,
+        type='favorite'
+    ).first()
+    if not beh:
+        return jsonify({'error': 'not favorited yet'}), 400
+
+    db.session.delete(beh)
+    # 更新热度
+    post = Post.query.get_or_404(post_id)
+    post.heat = max(post.heat - 1, 0)
+    db.session.commit()
+    return '', 204
\ No newline at end of file
diff --git a/Merge/back_wzy/utils/auth.py b/Merge/back_wzy/utils/auth.py
new file mode 100644
index 0000000..24704d1
--- /dev/null
+++ b/Merge/back_wzy/utils/auth.py
@@ -0,0 +1,38 @@
+# utils/auth.py
+import os
+import jwt
+from functools import wraps
+from flask import request, jsonify, current_app
+from models.user import User
+from app import db
+
+def generate_token(user_id):
+    payload = {
+        'user_id': user_id,
+        # you can add exp, iat here
+    }
+    token = jwt.encode(payload, current_app.config['SECRET_KEY'], algorithm='HS256')
+    return token
+
+def verify_token(token):
+    try:
+        payload = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])
+        user = User.query.get(payload['user_id'])
+        return user
+    except Exception:
+        return None
+
+def login_required(f):
+    @wraps(f)
+    def decorated(*args, **kwargs):
+        auth_header = request.headers.get('Authorization', None)
+        if not auth_header or not auth_header.startswith('Bearer '):
+            return jsonify({'error': 'Authorization header missing or invalid'}), 401
+        token = auth_header.split()[1]
+        user = verify_token(token)
+        if not user or user.status != 'active':
+            return jsonify({'error': 'Invalid or expired token'}), 401
+        # attach user to request context if needed
+        request.current_user = user
+        return f(*args, **kwargs)
+    return decorated
diff --git a/Merge/back_wzy/utils/serializers.py b/Merge/back_wzy/utils/serializers.py
new file mode 100644
index 0000000..1ed5445
--- /dev/null
+++ b/Merge/back_wzy/utils/serializers.py
@@ -0,0 +1,16 @@
+# utils/serializers.py
+from marshmallow import Schema, fields, validate, ValidationError
+
+class PostSchema(Schema):
+    user_id = fields.Int(required=True)
+    topic_id = fields.Int(required=False, allow_none=True)
+    type = fields.Str(validate=validate.OneOf(['text','image','video','document']), missing='text')
+    title = fields.Str(required=True, validate=validate.Length(min=1, max=255))
+    content = fields.Str(required=True)
+    media_urls = fields.List(fields.Url(), required=False)
+    status = fields.Str(validate=validate.OneOf(['draft','pending','published','deleted','rejected']), missing='draft')
+
+class CommentSchema(Schema):
+    user_id = fields.Int(required=True)
+    content = fields.Str(required=True, validate=validate.Length(min=1))
+    parent_id = fields.Int(required=False, allow_none=True)