Skip to content

[FEATURE] Collaborative Board CRUD over WebSocket #17

@ilkerciblak

Description

@ilkerciblak

Phase: 4.1
Title: Feature Implementation: Collaborative Board — Card CRUD over WebSocket


Description

As application's first real feature implementation, instrument Collaborative Card Board. Users will be able to create, update, delete and move cards on a board. All data transactions should be processed over websocket and latest data should be broadcasted to all connected clients in real time.

Note

Latest board state will be held in-memory on the backend.

On the other hand, even clients disconnects and re-connects to the server they should be retrieving latest state of the board and cards. Data persistence can easily achieve this goal. Despite this, data persistence in real-time communications can introduce concurrenct control problems. Thus, for only this issue latest state will be managed in-memory using mutexes. Data persistence and simple locking system will be introduces following issues.


Motivations

  • This is the first real feature that ties together the entire WebSocket infrastructure built so far
  • In-memory state keeps the implementation simple and focused on real-time mechanics
  • Seeing multiple browser tabs react to the same event in real time is the core learning objective of this phase

Tasks

  • Create internal/board/board.go — in-memory board state with a Card struct and a Board struct
  • Board must support: CreateCard, MoveCard, UpdateCard, DeleteCard operations
  • Board must be safe for concurrent use — multiple goroutines will call these methods simultaneously
  • Register WebSocket event handlers in internal/ws/router.go for all four card operations
  • Each handler must: deserialize the payload, mutate the board state, broadcast the updated event to all connected clients
  • Create app/board/page.tsx — a board UI with columns (Todo, In Progress, Done)
  • Each column renders its cards
  • Implement card creation from the UI — user types a title, selects a column, submits
  • Implement card deletion from the UI
  • Implement card movement between columns from the UI
  • All UI operations go through sendMessage — no direct HTTP calls

Technical Details

Card struct:
  type Card struct {
      ID     string `json:"id"`
      Title  string `json:"title"`
      Column string `json:"column"`
  }

Board struct:
  type Board struct {
      mu    sync.RWMutex
      cards map[string]Card
  }

Columns: "todo", "in-progress", "done"

Handler flow:
  1. Unmarshal payload into typed struct
  2. Mutate board state
  3. Marshal updated event
  4. hub.broadcastPayload(data)

Board instance should be created at server startup
and passed to the WebSocket router handlers via closure.

Acceptance Criteria

  • Creating a card in one browser tab appears in all other connected tabs instantly
  • Moving a card updates its column in all tabs
  • Deleting a card removes it from all tabs
  • Board state is consistent across all connected clients
  • Disconnecting and reconnecting shows the current board state
  • No HTTP endpoints used for board operations — everything over WebSocket

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions