kanban dashboard
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
package kanban
|
||||
|
||||
import "tm/pkg/response"
|
||||
|
||||
// CreateBoardRequest represents a request to create a new kanban board
|
||||
type CreateBoardRequest struct {
|
||||
Name string `json:"name" valid:"required~Board name is required,stringlength(1|100)~Board name must be between 1 and 100 characters"`
|
||||
Description string `json:"description" valid:"stringlength(0|500)~Description must not exceed 500 characters"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
UserID string `json:"-"` // Set from context/auth middleware
|
||||
}
|
||||
|
||||
// UpdateBoardRequest represents a request to update an existing board
|
||||
type UpdateBoardRequest struct {
|
||||
ID string `json:"id" valid:"required~Board ID is required"`
|
||||
Name *string `json:"name,omitempty" valid:"stringlength(1|100)~Board name must be between 1 and 100 characters"`
|
||||
Description *string `json:"description,omitempty" valid:"stringlength(0|500)~Description must not exceed 500 characters"`
|
||||
IsDefault *bool `json:"is_default,omitempty"`
|
||||
}
|
||||
|
||||
// CreateColumnRequest represents a request to create a new column
|
||||
type CreateColumnRequest struct {
|
||||
BoardID string `json:"board_id" valid:"required~Board ID is required"`
|
||||
Name string `json:"name" valid:"required~Column name is required,stringlength(1|50)~Column name must be between 1 and 50 characters"`
|
||||
Color string `json:"color" valid:"hexcolor~Color must be a valid hex color"`
|
||||
Order int `json:"order"`
|
||||
Limit *int `json:"limit,omitempty" valid:"range(1|100)~WIP limit must be between 1 and 100"`
|
||||
}
|
||||
|
||||
// UpdateColumnRequest represents a request to update an existing column
|
||||
type UpdateColumnRequest struct {
|
||||
ID string `json:"id" valid:"required~Column ID is required"`
|
||||
Name *string `json:"name,omitempty" valid:"stringlength(1|50)~Column name must be between 1 and 50 characters"`
|
||||
Color *string `json:"color,omitempty" valid:"hexcolor~Color must be a valid hex color"`
|
||||
Order *int `json:"order,omitempty"`
|
||||
Limit *int `json:"limit,omitempty" valid:"range(1|100)~WIP limit must be between 1 and 100"`
|
||||
}
|
||||
|
||||
// CreateCardRequest represents a request to create a new card
|
||||
type CreateCardRequest struct {
|
||||
ColumnID string `json:"column_id" valid:"required~Column ID is required"`
|
||||
TenderID string `json:"tender_id" valid:"required~Tender ID is required"`
|
||||
Title string `json:"title" valid:"required~Title is required,stringlength(1|200)~Title must be between 1 and 200 characters"`
|
||||
Order int `json:"order"`
|
||||
Priority CardPriority `json:"priority"`
|
||||
Labels []string `json:"labels,omitempty"`
|
||||
DueDate *int64 `json:"due_date,omitempty"` // Unix timestamp
|
||||
}
|
||||
|
||||
// UpdateCardRequest represents a request to update an existing card
|
||||
type UpdateCardRequest struct {
|
||||
ID string `json:"id" valid:"required~Card ID is required"`
|
||||
Title *string `json:"title,omitempty" valid:"stringlength(1|200)~Title must be between 1 and 200 characters"`
|
||||
Priority *CardPriority `json:"priority,omitempty"`
|
||||
Labels []string `json:"labels,omitempty"`
|
||||
DueDate *int64 `json:"due_date,omitempty"` // Unix timestamp
|
||||
}
|
||||
|
||||
// MoveCardRequest represents a request to move a card to a different column
|
||||
type MoveCardRequest struct {
|
||||
CardID string `json:"card_id" valid:"required~Card ID is required"`
|
||||
ColumnID string `json:"column_id" valid:"required~Column ID is required"`
|
||||
NewOrder int `json:"new_order"`
|
||||
}
|
||||
|
||||
// ReorderCardsRequest represents a request to reorder cards within a column
|
||||
type ReorderCardsRequest struct {
|
||||
ColumnID string `json:"column_id" valid:"required~Column ID is required"`
|
||||
CardOrders map[string]int `json:"card_orders" valid:"required~Card orders are required"`
|
||||
}
|
||||
|
||||
// ReorderColumnsRequest represents a request to reorder columns within a board
|
||||
type ReorderColumnsRequest struct {
|
||||
BoardID string `json:"board_id" valid:"required~Board ID is required"`
|
||||
ColumnOrders map[string]int `json:"column_orders" valid:"required~Column orders are required"`
|
||||
}
|
||||
|
||||
// BoardResponse represents a board in API responses
|
||||
type BoardResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Columns []ColumnResponse `json:"columns"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
UserID string `json:"user_id"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ColumnResponse represents a column in API responses
|
||||
type ColumnResponse struct {
|
||||
ID string `json:"id"`
|
||||
BoardID string `json:"board_id"`
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
Color string `json:"color"`
|
||||
Limit *int `json:"limit,omitempty"`
|
||||
Cards []CardResponse `json:"cards"`
|
||||
CardCount int `json:"card_count"`
|
||||
IsOverLimit bool `json:"is_over_limit"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
// CardResponse represents a card in API responses
|
||||
type CardResponse struct {
|
||||
ID string `json:"id"`
|
||||
ColumnID string `json:"column_id"`
|
||||
TenderID string `json:"tender_id"`
|
||||
Title string `json:"title"`
|
||||
Order int `json:"order"`
|
||||
Priority CardPriority `json:"priority"`
|
||||
Labels []string `json:"labels,omitempty"`
|
||||
DueDate *int64 `json:"due_date,omitempty"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
// BoardsListResponse represents the response for listing boards
|
||||
type BoardsListResponse struct {
|
||||
Boards []BoardResponse `json:"boards"`
|
||||
Meta *response.Meta `json:"-"`
|
||||
}
|
||||
|
||||
// BoardDetailResponse represents detailed board response with full column and card data
|
||||
type BoardDetailResponse struct {
|
||||
Board BoardResponse `json:"board"`
|
||||
Meta *response.Meta `json:"-"`
|
||||
}
|
||||
|
||||
// ToBoardResponse converts a Board entity to BoardResponse
|
||||
func (b *Board) ToResponse() *BoardResponse {
|
||||
return &BoardResponse{
|
||||
ID: b.ID.Hex(),
|
||||
Name: b.Name,
|
||||
Description: b.Description,
|
||||
Columns: make([]ColumnResponse, 0), // Will be populated by service
|
||||
IsDefault: b.IsDefault,
|
||||
UserID: b.UserID,
|
||||
CreatedAt: b.CreatedAt,
|
||||
UpdatedAt: b.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// ToColumnResponse converts a Column entity to ColumnResponse
|
||||
func (c *Column) ToResponse() *ColumnResponse {
|
||||
return &ColumnResponse{
|
||||
ID: c.ID.Hex(),
|
||||
BoardID: c.BoardID,
|
||||
Name: c.Name,
|
||||
Order: c.Order,
|
||||
Color: c.Color,
|
||||
Limit: c.Limit,
|
||||
Cards: make([]CardResponse, 0), // Will be populated by service
|
||||
CardCount: 0, // Will be populated by service
|
||||
IsOverLimit: false, // Will be calculated by service
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// ToCardResponse converts a Card entity to CardResponse
|
||||
func (c *Card) ToResponse() *CardResponse {
|
||||
return &CardResponse{
|
||||
ID: c.ID.Hex(),
|
||||
ColumnID: c.ColumnID,
|
||||
TenderID: c.TenderID,
|
||||
Title: c.Title,
|
||||
Order: c.Order,
|
||||
Priority: c.Priority,
|
||||
Labels: c.Labels,
|
||||
DueDate: c.DueDate,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user