mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-27 14:57:15 +00:00
136fac6609
* feat(import): a partly imported workspace is marked until its owner keeps or deletes it (TASK-896)
A bundle import that hits a DATA error after pad-export.json was imported
keeps the partial workspace (the rule is now written in docs/api.md:
transport failure, validation reject and pre-creation refusal roll back;
only a post-mint data error keeps). The 400 that said "kept" was the only
record, and a client may never read it.
- workspace_import_status (side table, SQLite 131 / PG 104): instance-
local, never exported, purged with the workspace.
- The keep path writes {status: partial, note}. The note is SANITIZED:
a fixed category and a correlation id (imp-...); the raw error goes to
the server log under that id.
- GET /workspaces/{slug} carries import_status (omitempty); the note only
for owners and instance admins. The list carries the status only.
- PATCH /workspaces/{slug} {"clear_import_status": true} clears it
(owner-only, like every workspace PATCH).
- pad workspace list marks it "partly imported" (text only; the JSON
mirrors the MCP workspace-list resource).
- Web: a banner on the workspace landing page and settings, with the
reason for owners, "Keep it" (clear) and "Delete workspace".
Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS
* fix(import): a rollback that cannot remove the workspace marks it too; the docs name what keeps (TASK-896, codex r1)
Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS
* fix(import): only members who are admins read the note; the banner's note fetch is fenced on identity (TASK-896, codex r2)
Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS
67 lines
3.3 KiB
Go
67 lines
3.3 KiB
Go
package models
|
|
|
|
import "time"
|
|
|
|
type Workspace struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug"`
|
|
OwnerID string `json:"owner_id,omitempty"` // User ID of workspace owner
|
|
OwnerUsername string `json:"owner_username,omitempty"` // Populated by JOIN (not stored)
|
|
IsGuest bool `json:"is_guest,omitempty"` // True when user has grants but no membership
|
|
Description string `json:"description"`
|
|
Settings string `json:"settings"` // JSON
|
|
// Source records how the workspace was created — "web", "cli", or "mcp"
|
|
// (empty on rows predating migration 069). A cli/mcp origin means an
|
|
// agent surface created the workspace, so an agent is already wired up
|
|
// even before it creates its first item; the dashboard's
|
|
// has_agent_activity signal ORs this in (BUG-1557).
|
|
Source string `json:"source,omitempty"`
|
|
SortOrder int `json:"sort_order"`
|
|
Context *WorkspaceContext `json:"context,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
|
// ImportStatus is set only on a workspace a bundle import created and
|
|
// KEPT after a data error past the point of no return (TASK-896).
|
|
// Populated by the handlers from workspace_import_status, never stored
|
|
// on the workspaces row. Note is visible to owners and admins only.
|
|
ImportStatus *WorkspaceImportStatus `json:"import_status,omitempty"`
|
|
}
|
|
|
|
// WorkspaceImportStatus marks a workspace an import left partly built
|
|
// (TASK-896). Status is "partial"; Note is a server-composed, sanitized
|
|
// reason (a fixed category plus a correlation id the server log carries).
|
|
type WorkspaceImportStatus struct {
|
|
Status string `json:"status"`
|
|
Note string `json:"note,omitempty"`
|
|
}
|
|
|
|
type WorkspaceCreate struct {
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug,omitempty"` // auto-generated if empty
|
|
OwnerID string `json:"owner_id,omitempty"` // set by server from authenticated user
|
|
Description string `json:"description,omitempty"`
|
|
Settings string `json:"settings,omitempty"`
|
|
Context *WorkspaceContext `json:"context,omitempty"`
|
|
Template string `json:"template,omitempty"` // workspace template name (e.g. "startup", "scrum", "product")
|
|
// Source is the creation surface — "web", "cli", or "mcp". It is set
|
|
// SERVER-SIDE ONLY: the HTTP create handler derives it authoritatively
|
|
// from the request's auth shape (actorFromRequest), so `json:"-"` keeps
|
|
// it out of the request body — a web client must not be able to spoof
|
|
// "cli" to self-suppress the connect-agent/onboarding prompts. Direct
|
|
// store callers (cloud auto-create, import) leave it "" so they aren't
|
|
// treated as agent-created. See BUG-1557.
|
|
Source string `json:"-"`
|
|
}
|
|
|
|
type WorkspaceUpdate struct {
|
|
Name *string `json:"name,omitempty"`
|
|
Description *string `json:"description,omitempty"`
|
|
Settings *string `json:"settings,omitempty"`
|
|
Context *WorkspaceContext `json:"context,omitempty"`
|
|
// ClearImportStatus removes a partial-import marker (TASK-896): the
|
|
// owner has inspected what an interrupted import kept and keeps it.
|
|
ClearImportStatus bool `json:"clear_import_status,omitempty"`
|
|
}
|