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:
@@ -50,13 +50,14 @@ func (r *ProjectRepository) List(ctx context.Context) ([]design.ProjectSummary,
|
||||
items := make([]design.ProjectSummary, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, design.ProjectSummary{
|
||||
ID: row.ID,
|
||||
UserID: fromPGUUID(row.UserID),
|
||||
Title: row.Title,
|
||||
Brief: row.Brief,
|
||||
Status: design.ProjectStatus(row.Status),
|
||||
Thumbnail: row.Thumbnail,
|
||||
UpdatedAt: row.UpdatedAt.Time,
|
||||
ID: row.ID,
|
||||
UserID: fromPGUUID(row.UserID),
|
||||
Title: row.Title,
|
||||
Brief: row.Brief,
|
||||
Status: design.ProjectStatus(row.Status),
|
||||
Thumbnail: row.Thumbnail,
|
||||
BrandKitID: fromPGText(row.BrandKitID),
|
||||
UpdatedAt: row.UpdatedAt.Time,
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
@@ -81,13 +82,14 @@ func (r *ProjectRepository) ListPage(ctx context.Context, limit int64, offset in
|
||||
items := make([]design.ProjectSummary, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, design.ProjectSummary{
|
||||
ID: row.ID,
|
||||
UserID: fromPGUUID(row.UserID),
|
||||
Title: row.Title,
|
||||
Brief: row.Brief,
|
||||
Status: design.ProjectStatus(row.Status),
|
||||
Thumbnail: row.Thumbnail,
|
||||
UpdatedAt: row.UpdatedAt.Time,
|
||||
ID: row.ID,
|
||||
UserID: fromPGUUID(row.UserID),
|
||||
Title: row.Title,
|
||||
Brief: row.Brief,
|
||||
Status: design.ProjectStatus(row.Status),
|
||||
Thumbnail: row.Thumbnail,
|
||||
BrandKitID: fromPGText(row.BrandKitID),
|
||||
UpdatedAt: row.UpdatedAt.Time,
|
||||
})
|
||||
}
|
||||
return items, nil
|
||||
@@ -129,6 +131,7 @@ func (r *ProjectRepository) Get(ctx context.Context, id string) (design.Project,
|
||||
SnapshotID: row.SnapshotID,
|
||||
Canvas: row.Canvas,
|
||||
LastThreadID: row.LastThreadID,
|
||||
BrandKitID: fromPGText(row.BrandKitID),
|
||||
UpdatedAt: row.UpdatedAt.Time,
|
||||
Viewport: design.Viewport{
|
||||
X: row.ViewportX,
|
||||
@@ -165,6 +168,7 @@ func (r *ProjectRepository) Save(ctx context.Context, project design.Project) er
|
||||
Version: project.Version,
|
||||
SnapshotID: project.SnapshotID,
|
||||
LastThreadID: project.LastThreadID,
|
||||
BrandKitID: toPGText(project.BrandKitID),
|
||||
ViewportX: project.Viewport.X,
|
||||
ViewportY: project.Viewport.Y,
|
||||
ViewportK: project.Viewport.K,
|
||||
@@ -463,6 +467,18 @@ func fromPGUUID(value pgtype.UUID) string {
|
||||
return uuid.UUID(value.Bytes).String()
|
||||
}
|
||||
|
||||
func toPGText(value string) pgtype.Text {
|
||||
value = strings.TrimSpace(value)
|
||||
return pgtype.Text{String: value, Valid: value != ""}
|
||||
}
|
||||
|
||||
func fromPGText(value pgtype.Text) string {
|
||||
if !value.Valid {
|
||||
return ""
|
||||
}
|
||||
return value.String
|
||||
}
|
||||
|
||||
func insertProjectOutboxEvent(ctx context.Context, tx pgx.Tx, project design.Project, eventType string) error {
|
||||
eventID := uuid.NewString()
|
||||
createdAt := project.UpdatedAt
|
||||
|
||||
Reference in New Issue
Block a user