← FC Coder · HomePhase 03 · Lesson 37 · 60 min
Lesson37
Phase Three · Fullstack · Matchday 37 · Visibility

公开 vs 私有
阵容广场 · 私下藏

Today's 3 Jobs · 今天这三件事
  1. 01
    squads.isPublic boolean 字段 + push
    默认 false
  2. 02
    /profile 过滤 + /discover 列公开
    派生 canView
  3. 03
    🌟 双用户测试 · 私有藏起来 · 公开可见
    权限边界

权限派生(同 22 课心法)+ DB 层 .where 过滤。`isPublic` boolean · `/profile/[name]` 过滤别人不看私有 · `/discover` 公开广场。AI Supervised + 父亲必看(权限是高风险)。

Concept · 派生权限 + DB 过滤

canView 一行算

Chalk Board · canView
// 派生 · 不存 state
const canView = squad.userId === me?.id || squad.isPublic;
派生
canView = squad.userId === me.id || squad.isPublic
DB
.where(eq(squads.isPublic, true))
细节
/squads/[id] 详情页也要加守护

砍 —— 不教 可编辑 / 可评论 / 可复制 等多权限。今天二元。

Half 2 · 在屏幕上

字段 · 过滤 · 测试 · AI

01isPublic 字段 + 表单
01Min

Cursor + pnpm dev

老三件套。
02Min

squads.isPublic = integer({mode:'boolean'}).notNull().default(false)

push。
03Min

/squads/new 表单加 <input type='checkbox' name='isPublic'/>

createSquad 内 isPublic = formData.get('isPublic') === 'on'。
02过滤 + discover
04Min

/profile/[name] 过滤 visible = userSquads.filter(s => s.isPublic || s.userId === me.id)

派生权限。
05Min

新建 app/discover/page.tsx · server 查 .where(eq(squads.isPublic, true))

公开广场。
03双用户测试 + AI toggle
06Min

登 '哈兰德' · 创 2 个(1 公 1 私)

form 上勾选 / 不勾选 isPublic。
07Min

🌟 隐身登 '福登' · 访问 /profile/哈兰德

只看到 1 个公开。私有藏起来。
08Min

访问 /discover · 看公开那个

广场显示所有公开阵容。
09Min

AI Supervised:加 togglePublic action

Cmd+K · '切换 isPublic · 权限检查 squad.userId === currentUser.id'。父亲必看。
10Min

📸 截图 3 页对比

Phase 3 第十二张战利品。
讲给爸爸听

4 题 · 权限边界

01isPublic 为什么 boolean 不存复杂权限?Hint ↓

规则简单(二元)。Phase 5 才上 role-based。

02canView 为什么派生?Hint ↓

squad.userId === me.id || squad.isPublic 一行算。第 22 课心法。

03/discover 怎么排除私有?Hint ↓

.where(eq(isPublic, true)) SQL 层过滤更稳。

04URL 直访 /squads/[id] 看私有怎么办?Hint ↓

详情页也加 canView 检查。不然漏。

温度计

给「公开广场」打分

今天难度Difficulty
0
今天开心Fun
0
Final Whistle · 终场哨

阵容有公开 · 有私下 —— 隐私边界立起来。

还有 10 步没打勾。Step 7 隐身看到差别 = 算过。