feat(server): add brand kit management and project binding

Add a brand kit domain with memory and postgres stores, a BrandKitService
for CRUD and resolution, and REST endpoints to list, upsert, and delete
brand kits. Projects can bind a brand kit whose resolved context and
reference images feed into the agent's long-term memory and design prompts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-10 20:58:55 +08:00
parent 3653474355
commit 789f51b29e
38 changed files with 2165 additions and 135 deletions
@@ -26,6 +26,29 @@ type AgentMessage struct {
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
type AuthVerificationCode struct {
ID string `json:"id"`
Region string `json:"region"`
Channel string `json:"channel"`
Target string `json:"target"`
Purpose string `json:"purpose"`
CodeHash string `json:"code_hash"`
Attempts int32 `json:"attempts"`
ExpiresAt pgtype.Timestamptz `json:"expires_at"`
ConsumedAt pgtype.Timestamptz `json:"consumed_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
type BrandKit struct {
ID string `json:"id"`
UserID pgtype.UUID `json:"user_id"`
Name string `json:"name"`
Document []byte `json:"document"`
IsDefault bool `json:"is_default"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type CanvasConnection struct {
ID string `json:"id"`
ProjectID string `json:"project_id"`
@@ -81,6 +104,14 @@ type CanvasSnapshot struct {
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
type MockupBlob struct {
DataID string `json:"data_id"`
Width int32 `json:"width"`
Height int32 `json:"height"`
Data []byte `json:"data"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
type OutboxEvent struct {
ID string `json:"id"`
UserID pgtype.UUID `json:"user_id"`
@@ -105,17 +136,61 @@ type Project struct {
Version string `json:"version"`
SnapshotID string `json:"snapshot_id"`
LastThreadID string `json:"last_thread_id"`
BrandKitID pgtype.Text `json:"brand_kit_id"`
ViewportX float64 `json:"viewport_x"`
ViewportY float64 `json:"viewport_y"`
ViewportK float64 `json:"viewport_k"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type User struct {
ID pgtype.UUID `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
type ProjectShareMember struct {
ID pgtype.UUID `json:"id"`
ProjectID string `json:"project_id"`
IdentifierType string `json:"identifier_type"`
IdentifierHash []byte `json:"identifier_hash"`
IdentifierCiphertext []byte `json:"identifier_ciphertext"`
Permission string `json:"permission"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type ProjectSharePolicy struct {
ProjectID string `json:"project_id"`
OwnerID pgtype.UUID `json:"owner_id"`
TokenHash []byte `json:"token_hash"`
TokenCiphertext []byte `json:"token_ciphertext"`
LinkPermission string `json:"link_permission"`
PolicyVersion int64 `json:"policy_version"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type ProjectShareVisit struct {
ID string `json:"id"`
ProjectID string `json:"project_id"`
VisitorHash []byte `json:"visitor_hash"`
UserID pgtype.UUID `json:"user_id"`
VisitCount int64 `json:"visit_count"`
FirstSeenAt pgtype.Timestamptz `json:"first_seen_at"`
LastSeenAt pgtype.Timestamptz `json:"last_seen_at"`
}
type User struct {
ID pgtype.UUID `json:"id"`
Email string `json:"email"`
Name string `json:"name"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
Region string `json:"region"`
PhoneCountryCode string `json:"phone_country_code"`
Phone string `json:"phone"`
AvatarUrl string `json:"avatar_url"`
PasswordHash string `json:"password_hash"`
WechatOpenID string `json:"wechat_open_id"`
WechatUnionID string `json:"wechat_union_id"`
GoogleSubject string `json:"google_subject"`
PhoneVerifiedAt pgtype.Timestamptz `json:"phone_verified_at"`
EmailVerifiedAt pgtype.Timestamptz `json:"email_verified_at"`
LastLoginAt pgtype.Timestamptz `json:"last_login_at"`
}