Changeset 0.21.1.1 (#87)

This commit is contained in:
2026-03-01 16:40:26 +00:00
parent 70aa78e486
commit 09c7281552
20 changed files with 853 additions and 102 deletions

View File

@@ -268,3 +268,24 @@ func (s *ChannelStore) UserOwns(ctx context.Context, channelID, userID string) (
channelID, userID).Scan(&exists)
return exists, err
}
// ResolveWorkspaceID returns the effective workspace for a channel.
// Resolution: channel.workspace_id > project.workspace_id.
// Returns empty string if no workspace is bound.
func (s *ChannelStore) ResolveWorkspaceID(ctx context.Context, channelID string) (string, error) {
var wsID sql.NullString
err := DB.QueryRowContext(ctx, `
SELECT COALESCE(c.workspace_id, p.workspace_id)
FROM channels c
LEFT JOIN project_channels pc ON pc.channel_id = c.id
LEFT JOIN projects p ON p.id = pc.project_id
WHERE c.id = ?
LIMIT 1`, channelID).Scan(&wsID)
if err != nil {
if err == sql.ErrNoRows {
return "", nil
}
return "", err
}
return NullableString(wsID), nil
}

View File

@@ -37,11 +37,11 @@ func (s *ProjectStore) Create(ctx context.Context, p *models.Project) error {
func (s *ProjectStore) GetByID(ctx context.Context, id string) (*models.Project, error) {
var p models.Project
var teamID sql.NullString
var teamID, workspaceID sql.NullString
var archived int
err := DB.QueryRowContext(ctx, `
SELECT p.id, p.name, p.description, p.color, p.icon, p.scope,
p.owner_id, p.team_id, p.is_archived, p.settings,
p.owner_id, p.team_id, p.is_archived, p.workspace_id, p.settings,
p.created_at, p.updated_at,
(SELECT COUNT(*) FROM project_channels WHERE project_id = p.id),
(SELECT COUNT(*) FROM project_knowledge_bases WHERE project_id = p.id),
@@ -49,7 +49,7 @@ func (s *ProjectStore) GetByID(ctx context.Context, id string) (*models.Project,
FROM projects p
WHERE p.id = ?`, id).Scan(
&p.ID, &p.Name, &p.Description, &p.Color, &p.Icon, &p.Scope,
&p.OwnerID, &teamID, &archived, &p.Settings,
&p.OwnerID, &teamID, &archived, &workspaceID, &p.Settings,
st(&p.CreatedAt), st(&p.UpdatedAt),
&p.ChannelCount, &p.KBCount, &p.NoteCount,
)
@@ -58,6 +58,7 @@ func (s *ProjectStore) GetByID(ctx context.Context, id string) (*models.Project,
}
p.IsArchived = archived != 0
p.TeamID = NullableStringPtr(teamID)
p.WorkspaceID = NullableStringPtr(workspaceID)
return &p, nil
}
@@ -85,6 +86,9 @@ func (s *ProjectStore) Update(ctx context.Context, id string, patch models.Proje
if patch.IsArchived != nil {
add("is_archived", boolToInt(*patch.IsArchived))
}
if patch.WorkspaceID != nil {
add("workspace_id", models.NullString(patch.WorkspaceID))
}
if len(patch.Settings) > 0 {
// Merge: read existing settings, overlay with patch values, write back.
var existing models.JSONMap
@@ -142,7 +146,7 @@ func (s *ProjectStore) Delete(ctx context.Context, id string) error {
func (s *ProjectStore) ListForUser(ctx context.Context, userID string, teamIDs []string, includeArchived bool) ([]models.Project, error) {
q := `
SELECT p.id, p.name, p.description, p.color, p.icon, p.scope,
p.owner_id, p.team_id, p.is_archived, p.settings,
p.owner_id, p.team_id, p.is_archived, p.workspace_id, p.settings,
p.created_at, p.updated_at,
(SELECT COUNT(*) FROM project_channels WHERE project_id = p.id),
(SELECT COUNT(*) FROM project_knowledge_bases WHERE project_id = p.id),
@@ -433,11 +437,11 @@ func (s *ProjectStore) queryProjects(ctx context.Context, q string, args ...inte
var result []models.Project
for rows.Next() {
var p models.Project
var teamID sql.NullString
var teamID, workspaceID sql.NullString
var archived int
if err := rows.Scan(
&p.ID, &p.Name, &p.Description, &p.Color, &p.Icon, &p.Scope,
&p.OwnerID, &teamID, &archived, &p.Settings,
&p.OwnerID, &teamID, &archived, &workspaceID, &p.Settings,
st(&p.CreatedAt), st(&p.UpdatedAt),
&p.ChannelCount, &p.KBCount, &p.NoteCount,
); err != nil {
@@ -445,6 +449,7 @@ func (s *ProjectStore) queryProjects(ctx context.Context, q string, args ...inte
}
p.IsArchived = archived != 0
p.TeamID = NullableStringPtr(teamID)
p.WorkspaceID = NullableStringPtr(workspaceID)
result = append(result, p)
}
return result, rows.Err()