7.8 KiB
7.8 KiB
1. Project Scaffolding
- 1.1 Initialize Go module (
go mod init github.com/dcgsteve/pcli) - 1.2 Create directory structure:
cmd/,client/,model/,output/,logging/ - 1.3 Add Cobra dependency (
go get github.com/spf13/cobra) - 1.4 Create
main.goentry point that callscmd.Execute()
2. Logging
- 2.1 Implement
logging/logging.go—NewLogger(level string) *slog.Loggerthat parses level string, creates JSON handler writing to stderr
3. Model Types
- 3.1 Define
model/types.go— Project, Board, List, Card, Comment, TaskList, Task, Label, Action, CardLabel, CardMembership structs with JSON tags and pointer types for nullable fields - 3.2 Define
Envelopestruct (Data any,Error *string) inmodel/types.go - 3.3 Define
APIErrorstruct (StatusCode int, Message string) implementing theerrorinterface
4. Output Formatting
- 4.1 Implement
output/output.go—Print(data any, format string, w io.Writer)function that switches on format - 4.2 Implement JSON output mode — marshal
Envelope{Data: data, Error: nil}to stdout - 4.3 Implement error output —
PrintError(err error, format string, w io.Writer)that writesEnvelope{Data: nil, Error: msg}for JSON, or error to stderr for table - 4.4 Implement table output mode — tabwriter-based rendering with per-resource column definitions
5. Base HTTP Client
- 5.1 Implement
client/client.go—Clientstruct with BaseURL, Token, HTTPClient, Logger fields - 5.2 Implement
NewClient(baseURL, token string, logger *slog.Logger) *Client - 5.3 Implement
Do(ctx, method, path string, body any) (json.RawMessage, error)— URL construction, bearer header, JSON marshal/unmarshal, DEBUG logging with method/path/status/duration - 5.4 Implement
APIErrorhandling — map 4xx/5xx responses to APIError, WARN logging on errors - 5.5 Implement
DoNoBody(ctx, method, path string) (json.RawMessage, error)convenience method for GET/DELETE
6. Root Command and Global Flags
- 6.1 Implement
cmd/root.go— root Cobra command with--format,--url,--token,--log-levelpersistent flags - 6.2 Implement
PersistentPreRunE— resolve URL/token from flags or env vars (flag > env), validate both present, initialize logger, create client instance - 6.3 Wire output format into a shared variable accessible by all subcommands
7. Client — Project Operations
- 7.1 Implement
client/projects.go—ListProjects(ctx) ([]model.Project, error) - 7.2 Implement
GetProject(ctx, id string) (*model.Project, error)
8. Client — Board Operations
- 8.1 Implement
client/boards.go—GetBoard(ctx, id string) (*model.Board, error) - 8.2 Implement
ListBoardActions(ctx, boardId string, limit int) ([]model.Action, error)with cursor-based pagination usingbeforeId
9. Client — Card Operations
- 9.1 Implement
client/cards.go—GetCard(ctx, id string) (*model.Card, error) - 9.2 Implement
CreateCard(ctx, listId string, fields) (*model.Card, error) - 9.3 Implement
UpdateCard(ctx, id string, fields) (*model.Card, error) - 9.4 Implement
DeleteCard(ctx, id string) error - 9.5 Implement
DuplicateCard(ctx, id string, name *string, position *float64) (*model.Card, error) - 9.6 Implement
ListCards(ctx, listId string, limit int) ([]model.Card, error)with cursor-based pagination usingbefore - 9.7 Implement
ListCardActions(ctx, cardId string, limit int) ([]model.Action, error)with cursor-based pagination usingbeforeId - 9.8 Implement
ListCardsByBoard(ctx, boardId string, limit int) ([]model.CardWithList, error)— multi-call enrichment: get board → get cards per list → inject listName - 9.9 Implement
AddCardLabel(ctx, cardId, labelId string) error - 9.10 Implement
RemoveCardLabel(ctx, cardId, labelId string) error - 9.11 Implement
AddCardMember(ctx, cardId, userId string) error - 9.12 Implement
RemoveCardMember(ctx, cardId, userId string) error
10. Client — Comment Operations
- 10.1 Implement
client/comments.go—ListComments(ctx, cardId string, limit int) ([]model.Comment, error)with cursor-based pagination usingbeforeId - 10.2 Implement
CreateComment(ctx, cardId, text string) (*model.Comment, error) - 10.3 Implement
UpdateComment(ctx, id, text string) (*model.Comment, error) - 10.4 Implement
DeleteComment(ctx, id string) error
11. Client — Task List Operations
- 11.1 Implement
client/task_lists.go—CreateTaskList(ctx, cardId string, fields) (*model.TaskList, error) - 11.2 Implement
GetTaskList(ctx, id string) (*model.TaskList, error) - 11.3 Implement
UpdateTaskList(ctx, id string, fields) (*model.TaskList, error) - 11.4 Implement
DeleteTaskList(ctx, id string) error
12. Client — Task Operations
- 12.1 Implement
client/tasks.go—CreateTask(ctx, taskListId string, fields) (*model.Task, error) - 12.2 Implement
UpdateTask(ctx, id string, fields) (*model.Task, error) - 12.3 Implement
DeleteTask(ctx, id string) error
13. Client — Label Operations
- 13.1 Implement
client/labels.go—CreateLabel(ctx, boardId string, fields) (*model.Label, error) - 13.2 Implement
UpdateLabel(ctx, id string, fields) (*model.Label, error) - 13.3 Implement
DeleteLabel(ctx, id string) error
14. CLI — Project Commands
- 14.1 Implement
cmd/project.go—projectparent command,project listsubcommand,project get <id>subcommand
15. CLI — Board Commands
- 15.1 Implement
cmd/board.go—boardparent command,board get <id>subcommand,board actions <id>subcommand with--limitflag
16. CLI — Card Commands
- 16.1 Implement
cmd/card.go—cardparent command - 16.2 Implement
card listsubcommand with mutually required--board/--listflags and--limit - 16.3 Implement
card get <id>subcommand - 16.4 Implement
card createsubcommand with--list,--name(required),--description,--type,--position,--due-date,--due-completedflags - 16.5 Implement
card update <id>subcommand with optional update flags - 16.6 Implement
card delete <id>subcommand - 16.7 Implement
card duplicate <id>subcommand with optional--name,--position - 16.8 Implement
card move <id>subcommand with required--listand optional--position - 16.9 Implement
card assign <id>andcard unassign <id>subcommands with required--user - 16.10 Implement
card add-label <id>andcard remove-label <id>subcommands with required--label - 16.11 Implement
card actions <id>subcommand with--limit
17. CLI — Comment Commands
- 17.1 Implement
cmd/comment.go—commentparent command,comment listwith--cardand--limit,comment createwith--cardand--text,comment update <id>with--text,comment delete <id>
18. CLI — Task List Commands
- 18.1 Implement
cmd/task_list.go—task-listparent command,task-list createwith--card,--name, optional flags,task-list get <id>,task-list update <id>,task-list delete <id>
19. CLI — Task Commands
- 19.1 Implement
cmd/task.go—taskparent command,task createwith--task-list,--name, optional flags,task update <id>with optional flags,task delete <id>
20. CLI — Label Commands
- 20.1 Implement
cmd/label.go—labelparent command,label createwith--board,--name, optional--color,--position,label update <id>,label delete <id>
21. Build and Verify
- 21.1 Verify
go buildproduces a clean binary - 21.2 Verify
pcli --helpdisplays all commands and global flags - 21.3 Verify error output when
PLANKA_URL/PLANKA_TOKENare missing - 21.4 Add README.md with installation, configuration, and usage examples