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:
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -11,15 +11,20 @@ import (
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
ClearDefaultBrandKits(ctx context.Context, arg ClearDefaultBrandKitsParams) error
|
||||
CreateCanvasSnapshot(ctx context.Context, arg CreateCanvasSnapshotParams) error
|
||||
CreateConnection(ctx context.Context, arg CreateConnectionParams) error
|
||||
CreateMessage(ctx context.Context, arg CreateMessageParams) error
|
||||
DeleteBrandKit(ctx context.Context, arg DeleteBrandKitParams) (string, error)
|
||||
DeleteConnectionsByProject(ctx context.Context, arg DeleteConnectionsByProjectParams) error
|
||||
DeleteMessagesByProject(ctx context.Context, arg DeleteMessagesByProjectParams) error
|
||||
DeleteNodesByProject(ctx context.Context, arg DeleteNodesByProjectParams) error
|
||||
DeleteProject(ctx context.Context, arg DeleteProjectParams) error
|
||||
GetBrandKit(ctx context.Context, arg GetBrandKitParams) (BrandKit, error)
|
||||
GetCanvasSnapshot(ctx context.Context, arg GetCanvasSnapshotParams) (CanvasSnapshot, error)
|
||||
GetDefaultBrandKit(ctx context.Context, userID pgtype.UUID) (BrandKit, error)
|
||||
GetProject(ctx context.Context, arg GetProjectParams) (Project, error)
|
||||
ListBrandKits(ctx context.Context, userID pgtype.UUID) ([]BrandKit, error)
|
||||
ListConnectionsByProject(ctx context.Context, arg ListConnectionsByProjectParams) ([]CanvasConnection, error)
|
||||
ListMessagesByProject(ctx context.Context, arg ListMessagesByProjectParams) ([]AgentMessage, error)
|
||||
ListNodesByProject(ctx context.Context, arg ListNodesByProjectParams) ([]CanvasNode, error)
|
||||
@@ -27,6 +32,7 @@ type Querier interface {
|
||||
ListProjectsPage(ctx context.Context, arg ListProjectsPageParams) ([]ListProjectsPageRow, error)
|
||||
LockProject(ctx context.Context, arg LockProjectParams) (LockProjectRow, error)
|
||||
UpdateProjectCanvasSnapshot(ctx context.Context, arg UpdateProjectCanvasSnapshotParams) error
|
||||
UpsertBrandKit(ctx context.Context, arg UpsertBrandKitParams) (BrandKit, error)
|
||||
UpsertCanvasNode(ctx context.Context, arg UpsertCanvasNodeParams) error
|
||||
UpsertProject(ctx context.Context, arg UpsertProjectParams) error
|
||||
}
|
||||
|
||||
@@ -11,6 +11,22 @@ import (
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
const clearDefaultBrandKits = `-- name: ClearDefaultBrandKits :exec
|
||||
UPDATE brand_kits
|
||||
SET is_default = FALSE
|
||||
WHERE user_id = $1 AND is_default = TRUE AND id <> $2
|
||||
`
|
||||
|
||||
type ClearDefaultBrandKitsParams struct {
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
func (q *Queries) ClearDefaultBrandKits(ctx context.Context, arg ClearDefaultBrandKitsParams) error {
|
||||
_, err := q.db.Exec(ctx, clearDefaultBrandKits, arg.UserID, arg.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const createCanvasSnapshot = `-- name: CreateCanvasSnapshot :exec
|
||||
INSERT INTO canvas_snapshots (id, project_id, user_id, version, canvas, viewport_json, nodes_json, connections_json, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
@@ -140,6 +156,24 @@ func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) er
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteBrandKit = `-- name: DeleteBrandKit :one
|
||||
DELETE FROM brand_kits
|
||||
WHERE id = $1 AND user_id = $2
|
||||
RETURNING id
|
||||
`
|
||||
|
||||
type DeleteBrandKitParams struct {
|
||||
ID string `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteBrandKit(ctx context.Context, arg DeleteBrandKitParams) (string, error) {
|
||||
row := q.db.QueryRow(ctx, deleteBrandKit, arg.ID, arg.UserID)
|
||||
var id string
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
const deleteConnectionsByProject = `-- name: DeleteConnectionsByProject :exec
|
||||
DELETE FROM canvas_connections
|
||||
WHERE project_id = $1 AND user_id = $2
|
||||
@@ -200,6 +234,32 @@ func (q *Queries) DeleteProject(ctx context.Context, arg DeleteProjectParams) er
|
||||
return err
|
||||
}
|
||||
|
||||
const getBrandKit = `-- name: GetBrandKit :one
|
||||
SELECT id, user_id, name, document, is_default, created_at, updated_at
|
||||
FROM brand_kits
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`
|
||||
|
||||
type GetBrandKitParams struct {
|
||||
ID string `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetBrandKit(ctx context.Context, arg GetBrandKitParams) (BrandKit, error) {
|
||||
row := q.db.QueryRow(ctx, getBrandKit, arg.ID, arg.UserID)
|
||||
var i BrandKit
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.Document,
|
||||
&i.IsDefault,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getCanvasSnapshot = `-- name: GetCanvasSnapshot :one
|
||||
SELECT id, project_id, user_id, version, canvas, viewport_json, nodes_json, connections_json, created_at
|
||||
FROM canvas_snapshots
|
||||
@@ -229,8 +289,30 @@ func (q *Queries) GetCanvasSnapshot(ctx context.Context, arg GetCanvasSnapshotPa
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getDefaultBrandKit = `-- name: GetDefaultBrandKit :one
|
||||
SELECT id, user_id, name, document, is_default, created_at, updated_at
|
||||
FROM brand_kits
|
||||
WHERE user_id = $1 AND is_default = TRUE
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetDefaultBrandKit(ctx context.Context, userID pgtype.UUID) (BrandKit, error) {
|
||||
row := q.db.QueryRow(ctx, getDefaultBrandKit, userID)
|
||||
var i BrandKit
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.Document,
|
||||
&i.IsDefault,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getProject = `-- name: GetProject :one
|
||||
SELECT id, user_id, title, brief, status, thumbnail, canvas, version, snapshot_id, last_thread_id, viewport_x, viewport_y, viewport_k, updated_at
|
||||
SELECT id, user_id, title, brief, status, thumbnail, canvas, version, snapshot_id, last_thread_id, brand_kit_id, viewport_x, viewport_y, viewport_k, updated_at
|
||||
FROM projects
|
||||
WHERE id = $1 AND user_id = $2
|
||||
`
|
||||
@@ -254,6 +336,7 @@ func (q *Queries) GetProject(ctx context.Context, arg GetProjectParams) (Project
|
||||
&i.Version,
|
||||
&i.SnapshotID,
|
||||
&i.LastThreadID,
|
||||
&i.BrandKitID,
|
||||
&i.ViewportX,
|
||||
&i.ViewportY,
|
||||
&i.ViewportK,
|
||||
@@ -262,6 +345,41 @@ func (q *Queries) GetProject(ctx context.Context, arg GetProjectParams) (Project
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listBrandKits = `-- name: ListBrandKits :many
|
||||
SELECT id, user_id, name, document, is_default, created_at, updated_at
|
||||
FROM brand_kits
|
||||
WHERE user_id = $1
|
||||
ORDER BY updated_at DESC, id ASC
|
||||
`
|
||||
|
||||
func (q *Queries) ListBrandKits(ctx context.Context, userID pgtype.UUID) ([]BrandKit, error) {
|
||||
rows, err := q.db.Query(ctx, listBrandKits, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []BrandKit
|
||||
for rows.Next() {
|
||||
var i BrandKit
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.Document,
|
||||
&i.IsDefault,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listConnectionsByProject = `-- name: ListConnectionsByProject :many
|
||||
SELECT id, project_id, user_id, from_node_id, to_node_id
|
||||
FROM canvas_connections
|
||||
@@ -414,20 +532,21 @@ func (q *Queries) ListNodesByProject(ctx context.Context, arg ListNodesByProject
|
||||
}
|
||||
|
||||
const listProjects = `-- name: ListProjects :many
|
||||
SELECT id, user_id, title, brief, status, thumbnail, updated_at
|
||||
SELECT id, user_id, title, brief, status, thumbnail, brand_kit_id, updated_at
|
||||
FROM projects
|
||||
WHERE user_id = $1
|
||||
ORDER BY updated_at DESC
|
||||
`
|
||||
|
||||
type ListProjectsRow struct {
|
||||
ID string `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
Title string `json:"title"`
|
||||
Brief string `json:"brief"`
|
||||
Status string `json:"status"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
ID string `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
Title string `json:"title"`
|
||||
Brief string `json:"brief"`
|
||||
Status string `json:"status"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
BrandKitID pgtype.Text `json:"brand_kit_id"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListProjects(ctx context.Context, userID pgtype.UUID) ([]ListProjectsRow, error) {
|
||||
@@ -446,6 +565,7 @@ func (q *Queries) ListProjects(ctx context.Context, userID pgtype.UUID) ([]ListP
|
||||
&i.Brief,
|
||||
&i.Status,
|
||||
&i.Thumbnail,
|
||||
&i.BrandKitID,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
@@ -459,7 +579,7 @@ func (q *Queries) ListProjects(ctx context.Context, userID pgtype.UUID) ([]ListP
|
||||
}
|
||||
|
||||
const listProjectsPage = `-- name: ListProjectsPage :many
|
||||
SELECT id, user_id, title, brief, status, thumbnail, updated_at
|
||||
SELECT id, user_id, title, brief, status, thumbnail, brand_kit_id, updated_at
|
||||
FROM projects
|
||||
WHERE user_id = $1
|
||||
ORDER BY updated_at DESC
|
||||
@@ -473,13 +593,14 @@ type ListProjectsPageParams struct {
|
||||
}
|
||||
|
||||
type ListProjectsPageRow struct {
|
||||
ID string `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
Title string `json:"title"`
|
||||
Brief string `json:"brief"`
|
||||
Status string `json:"status"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
ID string `json:"id"`
|
||||
UserID pgtype.UUID `json:"user_id"`
|
||||
Title string `json:"title"`
|
||||
Brief string `json:"brief"`
|
||||
Status string `json:"status"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
BrandKitID pgtype.Text `json:"brand_kit_id"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListProjectsPage(ctx context.Context, arg ListProjectsPageParams) ([]ListProjectsPageRow, error) {
|
||||
@@ -498,6 +619,7 @@ func (q *Queries) ListProjectsPage(ctx context.Context, arg ListProjectsPagePara
|
||||
&i.Brief,
|
||||
&i.Status,
|
||||
&i.Thumbnail,
|
||||
&i.BrandKitID,
|
||||
&i.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
@@ -577,6 +699,51 @@ func (q *Queries) UpdateProjectCanvasSnapshot(ctx context.Context, arg UpdatePro
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertBrandKit = `-- name: UpsertBrandKit :one
|
||||
INSERT INTO brand_kits (id, user_id, name, document, is_default, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
document = EXCLUDED.document,
|
||||
is_default = EXCLUDED.is_default,
|
||||
updated_at = EXCLUDED.updated_at
|
||||
WHERE brand_kits.user_id = EXCLUDED.user_id
|
||||
RETURNING id, user_id, name, document, is_default, created_at, updated_at
|
||||
`
|
||||
|
||||
type UpsertBrandKitParams 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"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpsertBrandKit(ctx context.Context, arg UpsertBrandKitParams) (BrandKit, error) {
|
||||
row := q.db.QueryRow(ctx, upsertBrandKit,
|
||||
arg.ID,
|
||||
arg.UserID,
|
||||
arg.Name,
|
||||
arg.Document,
|
||||
arg.IsDefault,
|
||||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
)
|
||||
var i BrandKit
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
&i.Name,
|
||||
&i.Document,
|
||||
&i.IsDefault,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const upsertCanvasNode = `-- name: UpsertCanvasNode :exec
|
||||
INSERT INTO canvas_nodes (id, project_id, user_id, node_type, title, x, y, width, height, content, tone, status, sort_order, parent_id, layer_role, font_size, font_family, font_weight, color, text_align, line_height, letter_spacing, text_decoration, text_transform, opacity, fill_color, stroke_color, stroke_width, stroke_style, flip_x, flip_y, rotation)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32)
|
||||
@@ -688,8 +855,8 @@ func (q *Queries) UpsertCanvasNode(ctx context.Context, arg UpsertCanvasNodePara
|
||||
}
|
||||
|
||||
const upsertProject = `-- name: UpsertProject :exec
|
||||
INSERT INTO projects (id, user_id, title, brief, status, thumbnail, canvas, version, snapshot_id, last_thread_id, viewport_x, viewport_y, viewport_k, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||
INSERT INTO projects (id, user_id, title, brief, status, thumbnail, canvas, version, snapshot_id, last_thread_id, brand_kit_id, viewport_x, viewport_y, viewport_k, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
user_id = EXCLUDED.user_id,
|
||||
title = EXCLUDED.title,
|
||||
@@ -700,6 +867,7 @@ ON CONFLICT (id) DO UPDATE SET
|
||||
version = EXCLUDED.version,
|
||||
snapshot_id = EXCLUDED.snapshot_id,
|
||||
last_thread_id = EXCLUDED.last_thread_id,
|
||||
brand_kit_id = EXCLUDED.brand_kit_id,
|
||||
viewport_x = EXCLUDED.viewport_x,
|
||||
viewport_y = EXCLUDED.viewport_y,
|
||||
viewport_k = EXCLUDED.viewport_k,
|
||||
@@ -717,6 +885,7 @@ type UpsertProjectParams 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"`
|
||||
@@ -735,6 +904,7 @@ func (q *Queries) UpsertProject(ctx context.Context, arg UpsertProjectParams) er
|
||||
arg.Version,
|
||||
arg.SnapshotID,
|
||||
arg.LastThreadID,
|
||||
arg.BrandKitID,
|
||||
arg.ViewportX,
|
||||
arg.ViewportY,
|
||||
arg.ViewportK,
|
||||
|
||||
Reference in New Issue
Block a user