Skip to content

Feature/blog cms operations#10

Open
vH192Hv wants to merge 5 commits into
floatboatai:mainfrom
vH192Hv:feature/blog-cms-operations
Open

Feature/blog cms operations#10
vH192Hv wants to merge 5 commits into
floatboatai:mainfrom
vH192Hv:feature/blog-cms-operations

Conversation

@vH192Hv

@vH192Hv vH192Hv commented Jul 11, 2026

Copy link
Copy Markdown

设计方案

Wasp Spec 声明

blog-cms.wasp.ts 定义 10 个操作:

export const blogCmsSpec: Spec = [
  // Admin Queries
  query(getAllPosts,    { entities: ["Post", "Tag", "User"] }),
  query(getPost,        { entities: ["Post", "Tag", "User"] }),
  // Public Queries
  query(getPostBySlug,      { entities: ["Post", "Tag", "User"] }),
  query(getPublishedPosts,  { entities: ["Post", "Tag", "User"] }),
  // Admin Actions
  action(createPost,    { entities: ["Post", "Tag", "User"] }),
  action(updatePost,    { entities: ["Post", "Tag", "User"] }),
  action(deletePost,    { entities: ["Post"] }),
  // Tag Management
  query(getAllTags,     { entities: ["Tag"] }),
  action(createTag,     { entities: ["Tag"] }),
  action(deleteTag,     { entities: ["Tag"] }),
];

操作矩阵

操作 类型 权限 说明
getAllPosts Query Admin 分页 + 状态/标签/搜索过滤
getPost Query Admin 按 ID 取单帖
getPostBySlug Query Public 仅返回 PUBLISHED 帖子
getPublishedPosts Query Public 分页列表 + 标签过滤
createPost Action Admin slug 校验 + 状态校验
updatePost Action Admin 状态转换 + 标签替换 + publishedAt 管理
deletePost Action Admin 按 ID 删除
getAllTags Query Admin 含帖子计数
createTag Action Admin 名称/别名唯一性
deleteTag Action Admin Cascade 删除关联

Slug 校验规则

格式:   /^[a-z0-9]+(?:-[a-z0-9]+)*$/
长度:   3–200 字符
唯一:   数据库 @unique + 应用层 pre-check
冲突:   自动追加 -2, -3, ... 后缀
生成:   title → lowercase → replace spaces/underscores with hyphens

发布状态转换

DRAFT ──► PUBLISHED ──► ARCHIVED
  ▲          │              │
  └──────────┘              │
  ▲─────────────────────────┘

isAllowedTransition() 函数双端(服务端 + 客户端)校验转换合法性。

权限控制

function requireAdmin(context) {
  if (!context.user)  throw HttpError(401);
  if (!context.user.isAdmin) throw HttpError(403);
}

共享工具模块 utils.ts

浏览器+服务端安全的纯函数模块:

  • generateSlug(title) — 从标题生成 slug
  • isValidSlug(slug) — 格式 + 长度校验
  • isAllowedTransition(from, to) — 状态转换校验
  • getAllowedTransitions(status) — 获取允许的目标状态

执行方案

  • 创建 blog-cms.wasp.ts + 注册到 main.wasp.ts
  • 实现 utils.ts (shared slug helpers + status transitions)
  • 实现 operations.ts (10 个操作 + 权限 guard + slug 校验)
  • Zod schema 输入校验所有操作

文件变更

文件 操作 行数
template/app/src/blog-cms/blog-cms.wasp.ts 新增 36
template/app/src/blog-cms/utils.ts 新增 42
template/app/src/blog-cms/operations.ts 新增 502
template/app/main.wasp.ts 修改 +2

🔽 依赖 PR1 (schema) — 合并顺序第 2

vH192Hv and others added 5 commits July 9, 2026 21:30
- Add Post model with title, slug, content, excerpt, coverImage, status, timestamps
- Add Tag model with name and slug
- Add PostTag join table for many-to-many relationship
- Add PostStatus enum (DRAFT, PUBLISHED, ARCHIVED)
- Add posts relation to User model

Co-Authored-By: Claude <noreply@anthropic.com>
- Add seedBlogPosts function with sample posts and tags
- Register seed in main.wasp.ts db.seeds array

Co-Authored-By: Claude <noreply@anthropic.com>
- Define getAllPosts, getPost, getPostBySlug, getPublishedPosts queries
- Define createPost, updatePost, deletePost actions
- Define getAllTags, createTag, deleteTag tag operations
- Register blogCmsSpec in main.wasp.ts

Co-Authored-By: Claude <noreply@anthropic.com>
- Add isValidSlug, generateSlug with regex format + length checks
- Add ALLOWED_TRANSITIONS map and transition validation helpers
- File is browser+server safe (no wasp/server imports)

Co-Authored-By: Claude <noreply@anthropic.com>
…rmissions)

- Post queries: getAllPosts (admin, paginated, filters), getPost (admin, by ID),
  getPostBySlug (public, PUBLISHED only), getPublishedPosts (public, paginated)
- Post mutations: createPost (slug gen/validate, status validation),
  updatePost (status transitions, tag replacement, publishedAt mgmt),
  deletePost (by ID with existence check)
- Tag operations: getAllTags (with post count), createTag (name/slug uniqueness),
  deleteTag (cascade removes PostTag entries)
- Permission guard: requireAdmin on all mutating + admin-read operations
- Slug helpers imported from shared utils.ts
- Status transitions validated via isAllowedTransition from utils.ts

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant