mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 01:16:45 +08:00
Collapses the project-context resolution that had been copied across the issue, chat and quick-create claim paths (and would have been copied a fourth time) into one workspace-scoped, fail-closed resolver, and hydrates run_only autopilot project context on top of it. - Project and resource reads are both workspace-scoped, so a dangling or cross-tenant project reference can no longer lift another workspace's repository URL, local directory path, title or description into a claim. - A failed read is no longer treated as "there is no project". Transient failures reject the claim and preserve the task for the stale-dispatched reclaim rather than silently falling back to workspace repos. - Source rows (issue, chat session, autopilot run, autopilot) fail closed the same way. Previously a read error skipped the branch entirely and, because taskToResponse seeds the runtime workspace, sailed through the backstop isolation check — dispatching an agent with no issue context or, for chat, no input at all, bypassing the empty-input guard. - Workspace isolation is resolved authoritatively per branch and checked before any context is hydrated. For run_only autopilots that check had been a tautology, comparing the runtime workspace against itself. - run_only autopilots now receive their configured project's repositories and local_directory, the same contract issue-bound and quick-create tasks already had. Absorbs #7396. Its inline implementation is replaced by the shared resolver; the author's regression test is carried over unchanged. Co-authored-by: RAVN <[email protected]>
311 lines
8.2 KiB
Go
311 lines
8.2 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: project_resource.sql
|
|
|
|
package db
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const countProjectResources = `-- name: CountProjectResources :one
|
|
SELECT count(*) FROM project_resource WHERE project_id = $1
|
|
`
|
|
|
|
func (q *Queries) CountProjectResources(ctx context.Context, projectID pgtype.UUID) (int64, error) {
|
|
row := q.db.QueryRow(ctx, countProjectResources, projectID)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const createProjectResource = `-- name: CreateProjectResource :one
|
|
INSERT INTO project_resource (
|
|
project_id, workspace_id, resource_type, resource_ref, label, position, created_by
|
|
) VALUES (
|
|
$1, $2, $3, $4, $5, $6, $7
|
|
) RETURNING id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by
|
|
`
|
|
|
|
type CreateProjectResourceParams struct {
|
|
ProjectID pgtype.UUID `json:"project_id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
ResourceType string `json:"resource_type"`
|
|
ResourceRef []byte `json:"resource_ref"`
|
|
Label pgtype.Text `json:"label"`
|
|
Position int32 `json:"position"`
|
|
CreatedBy pgtype.UUID `json:"created_by"`
|
|
}
|
|
|
|
func (q *Queries) CreateProjectResource(ctx context.Context, arg CreateProjectResourceParams) (ProjectResource, error) {
|
|
row := q.db.QueryRow(ctx, createProjectResource,
|
|
arg.ProjectID,
|
|
arg.WorkspaceID,
|
|
arg.ResourceType,
|
|
arg.ResourceRef,
|
|
arg.Label,
|
|
arg.Position,
|
|
arg.CreatedBy,
|
|
)
|
|
var i ProjectResource
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteProjectResource = `-- name: DeleteProjectResource :exec
|
|
DELETE FROM project_resource WHERE id = $1
|
|
`
|
|
|
|
func (q *Queries) DeleteProjectResource(ctx context.Context, id pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteProjectResource, id)
|
|
return err
|
|
}
|
|
|
|
const getProjectResource = `-- name: GetProjectResource :one
|
|
SELECT id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by FROM project_resource
|
|
WHERE id = $1
|
|
`
|
|
|
|
func (q *Queries) GetProjectResource(ctx context.Context, id pgtype.UUID) (ProjectResource, error) {
|
|
row := q.db.QueryRow(ctx, getProjectResource, id)
|
|
var i ProjectResource
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getProjectResourceCounts = `-- name: GetProjectResourceCounts :many
|
|
SELECT project_id, count(*)::bigint AS resource_count
|
|
FROM project_resource
|
|
WHERE project_id = ANY($1::uuid[])
|
|
GROUP BY project_id
|
|
`
|
|
|
|
type GetProjectResourceCountsRow struct {
|
|
ProjectID pgtype.UUID `json:"project_id"`
|
|
ResourceCount int64 `json:"resource_count"`
|
|
}
|
|
|
|
func (q *Queries) GetProjectResourceCounts(ctx context.Context, projectIds []pgtype.UUID) ([]GetProjectResourceCountsRow, error) {
|
|
rows, err := q.db.Query(ctx, getProjectResourceCounts, projectIds)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []GetProjectResourceCountsRow{}
|
|
for rows.Next() {
|
|
var i GetProjectResourceCountsRow
|
|
if err := rows.Scan(&i.ProjectID, &i.ResourceCount); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const getProjectResourceInWorkspace = `-- name: GetProjectResourceInWorkspace :one
|
|
SELECT id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by FROM project_resource
|
|
WHERE id = $1 AND workspace_id = $2
|
|
`
|
|
|
|
type GetProjectResourceInWorkspaceParams struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
}
|
|
|
|
func (q *Queries) GetProjectResourceInWorkspace(ctx context.Context, arg GetProjectResourceInWorkspaceParams) (ProjectResource, error) {
|
|
row := q.db.QueryRow(ctx, getProjectResourceInWorkspace, arg.ID, arg.WorkspaceID)
|
|
var i ProjectResource
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const listProjectResources = `-- name: ListProjectResources :many
|
|
SELECT id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by FROM project_resource
|
|
WHERE project_id = $1
|
|
ORDER BY position ASC, created_at ASC
|
|
`
|
|
|
|
func (q *Queries) ListProjectResources(ctx context.Context, projectID pgtype.UUID) ([]ProjectResource, error) {
|
|
rows, err := q.db.Query(ctx, listProjectResources, projectID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ProjectResource{}
|
|
for rows.Next() {
|
|
var i ProjectResource
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listProjectResourcesForProjects = `-- name: ListProjectResourcesForProjects :many
|
|
SELECT id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by FROM project_resource
|
|
WHERE project_id = ANY($1::uuid[])
|
|
ORDER BY project_id, position ASC, created_at ASC
|
|
`
|
|
|
|
func (q *Queries) ListProjectResourcesForProjects(ctx context.Context, projectIds []pgtype.UUID) ([]ProjectResource, error) {
|
|
rows, err := q.db.Query(ctx, listProjectResourcesForProjects, projectIds)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ProjectResource{}
|
|
for rows.Next() {
|
|
var i ProjectResource
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listProjectResourcesInWorkspace = `-- name: ListProjectResourcesInWorkspace :many
|
|
SELECT id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by FROM project_resource
|
|
WHERE project_id = $1 AND workspace_id = $2
|
|
ORDER BY position ASC, created_at ASC
|
|
`
|
|
|
|
type ListProjectResourcesInWorkspaceParams struct {
|
|
ProjectID pgtype.UUID `json:"project_id"`
|
|
WorkspaceID pgtype.UUID `json:"workspace_id"`
|
|
}
|
|
|
|
// Workspace-scoped read for the daemon claim path. project_resource carries its
|
|
// own workspace_id, so a corrupt project reference cannot pull another tenant's
|
|
// repository URLs or local paths into a claim response.
|
|
func (q *Queries) ListProjectResourcesInWorkspace(ctx context.Context, arg ListProjectResourcesInWorkspaceParams) ([]ProjectResource, error) {
|
|
rows, err := q.db.Query(ctx, listProjectResourcesInWorkspace, arg.ProjectID, arg.WorkspaceID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ProjectResource{}
|
|
for rows.Next() {
|
|
var i ProjectResource
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const updateProjectResource = `-- name: UpdateProjectResource :one
|
|
UPDATE project_resource
|
|
SET resource_ref = $2,
|
|
label = $3,
|
|
position = $4
|
|
WHERE id = $1
|
|
RETURNING id, project_id, workspace_id, resource_type, resource_ref, label, position, created_at, created_by
|
|
`
|
|
|
|
type UpdateProjectResourceParams struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
ResourceRef []byte `json:"resource_ref"`
|
|
Label pgtype.Text `json:"label"`
|
|
Position int32 `json:"position"`
|
|
}
|
|
|
|
func (q *Queries) UpdateProjectResource(ctx context.Context, arg UpdateProjectResourceParams) (ProjectResource, error) {
|
|
row := q.db.QueryRow(ctx, updateProjectResource,
|
|
arg.ID,
|
|
arg.ResourceRef,
|
|
arg.Label,
|
|
arg.Position,
|
|
)
|
|
var i ProjectResource
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ProjectID,
|
|
&i.WorkspaceID,
|
|
&i.ResourceType,
|
|
&i.ResourceRef,
|
|
&i.Label,
|
|
&i.Position,
|
|
&i.CreatedAt,
|
|
&i.CreatedBy,
|
|
)
|
|
return i, err
|
|
}
|