Adds a free-form 'purpose' text field on Channel so agents (or anyone
creating a channel via API) can describe what the channel is for —
'debate broadcasts', 'security alerts', etc. — and other agents can
later find the right channel by intent rather than channel id.
Wire:
- Channel.purpose (text, nullable; TypeORM synchronize auto-adds)
- POST /api/channels accepts optional 'purpose' in body
- GET /api/channels returns purpose on every row (already returns the
full entity via {...c})
- PATCH /api/channels/:id { purpose } — member-or-public auth (mirrors
the close() rule). Today only 'purpose' is patchable; other fields
would get their own typed branch.
Frontend create form continues to omit the field — purpose stays optional.
This pairs with Fabric.OpenclawPlugin's fabric-channel-set-purpose tool +
fabric-channel-list returning purpose, so agent workflows can say 'find
an announce channel about X' instead of pinning a UUID.
56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
|
|
|
@Entity('channels')
|
|
@Index(['guildId', 'createdAt'])
|
|
export class Channel {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id!: string;
|
|
|
|
@Index()
|
|
@Column({ type: 'char', length: 36 })
|
|
guildId!: string;
|
|
|
|
@Column({ type: 'varchar', length: 120 })
|
|
name!: string;
|
|
|
|
@Column({
|
|
name: 'x_type',
|
|
type: 'enum',
|
|
enum: ['general', 'work', 'report', 'discuss', 'triage', 'custom', 'dm', 'announce'],
|
|
})
|
|
xType!: 'general' | 'work' | 'report' | 'discuss' | 'triage' | 'custom' | 'dm' | 'announce';
|
|
|
|
@Column({ type: 'varchar', length: 16, default: 'text' })
|
|
kind!: 'text' | 'announcement';
|
|
|
|
// Free-form description of what this channel is for — what topics get
|
|
// posted, who participates, why it exists. Surfaced via GET /api/channels
|
|
// so agents can pick a channel by intent ("which announce channel is for
|
|
// debate broadcasts?") without channel id hard-coded into workflows.
|
|
// Any channel member can set it via PATCH /api/channels/:id (writes
|
|
// require membership the same way moveToBypass / close do). The frontend
|
|
// create form does NOT post this today — purpose stays optional.
|
|
@Column({ type: 'text', nullable: true })
|
|
purpose!: string | null;
|
|
|
|
@Column({ type: 'boolean', default: false })
|
|
isPrivate!: boolean;
|
|
|
|
// public channels are visible to every guild member (including those who
|
|
// join after the channel was created); default off (unchecked)
|
|
@Column({ type: 'boolean', default: false })
|
|
isPublic!: boolean;
|
|
|
|
// closed (e.g. discussion-complete): history readable, new posts rejected
|
|
@Column({ type: 'boolean', default: false })
|
|
closed!: boolean;
|
|
|
|
@Index()
|
|
@Column({ default: 0 })
|
|
lastSeq!: number;
|
|
|
|
@CreateDateColumn()
|
|
@Index()
|
|
createdAt!: Date;
|
|
}
|