Skip to content

Claude/create feature f 01 qr r as j4 s14advm nn qhp2 la#1

Merged
Chris0Jeky merged 4 commits intomainfrom
claude/create-feature-f-01QrRAsJ4S14advmNnQhp2La
Nov 18, 2025
Merged

Claude/create feature f 01 qr r as j4 s14advm nn qhp2 la#1
Chris0Jeky merged 4 commits intomainfrom
claude/create-feature-f-01QrRAsJ4S14advmNnQhp2La

Conversation

@Chris0Jeky
Copy link
Copy Markdown
Owner

No description provided.

- Set up .NET 8 solution with 4 projects (Domain, Application, Infrastructure, Api)
- Implement Domain layer:
  * Core entities: Board, Column, Card, Label, CardLabel
  * Domain exceptions and error codes
  * Base Entity class with audit fields
  * Result pattern for error handling
- Implement Application layer:
  * Repository interfaces (IUnitOfWork pattern)
  * DTOs for all entities
  * Service layer with business logic (BoardService, ColumnService, CardService, LabelService)
  * WIP limit enforcement in CardService
- Implement Infrastructure layer:
  * EF Core DbContext with SQLite support
  * Entity configurations with Fluent API
  * Proper relationships and cascade rules
- Add comprehensive domain tests:
  * BoardTests, ColumnTests, CardTests, LabelTests
  * Test domain invariants and validation rules

All layers follow clean architecture principles with proper dependency flow.
- Infrastructure layer:
  * Repository pattern implementations for all entities
  * UnitOfWork pattern with transaction support
  * EF Core configurations with proper relationships
  * SQLite database support with DI setup

- API layer:
  * RESTful controllers for Boards, Columns, Cards, Labels
  * Proper error handling with domain error codes
  * CORS configuration for frontend
  * Swagger/OpenAPI documentation
  * Program.cs with DI configuration

Backend is now complete with full CRUD operations and WIP limit enforcement.
Ready to build with: dotnet build (requires internet for NuGet packages).
- Set up Vite + Vue 3 + TypeScript + TailwindCSS v3
- API layer:
  * Axios HTTP client with error handling
  * Type-safe API clients for boards, columns, cards, labels
  * Full CRUD operations for all entities

- State management with Pinia:
  * boardStore with complete state management
  * Computed properties for cards by column
  * Error handling and loading states

- Routing with Vue Router:
  * Boards list view
  * Individual board view with columns and cards

- Components:
  * BoardsListView - displays all boards, create new boards
  * BoardView - displays columns and cards for a board
  * ColumnLane - displays cards in a column with WIP limit indicator
  * CardItem - displays card with labels, due dates, blocked status

- Features:
  * Responsive design with Tailwind CSS
  * WIP limit visualization and warnings
  * Label color coding
  * Due date display with overdue indicators
  * Blocked card indicators
  * Clean, modern UI with proper loading and error states

Frontend ready to run with: npm install && npm run dev
- Complete README with:
  * Feature overview
  * Tech stack documentation
  * Getting started guide for both backend and frontend
  * Architecture documentation with folder structure
  * Domain model explanation
  * API endpoint reference
  * Database setup instructions
  * Development guidelines
  * Project roadmap

- .gitignore file:
  * Exclude build artifacts (bin/, obj/, node_modules/, dist/)
  * Exclude SQLite database files
  * Exclude IDE and OS files

Project is now fully documented and ready for use!
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request adds a Vue.js frontend application for the Taskdeck project, implementing a Kanban-style board management system. The frontend is built with Vue 3, TypeScript, Vite, and Tailwind CSS.

Key Changes

  • Complete Vue 3 + TypeScript frontend application setup with Vite build tooling
  • Implementation of board, column, card, and label management components and views
  • State management using Pinia with a centralized board store
  • API integration layer with Axios for backend communication

Reviewed Changes

Copilot reviewed 111 out of 114 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
frontend/taskdeck-web/package.json Project dependencies and scripts configuration
frontend/taskdeck-web/vite.config.ts Vite build configuration
frontend/taskdeck-web/tsconfig.*.json TypeScript configuration files for app and build tooling
frontend/taskdeck-web/tailwind.config.js Tailwind CSS configuration
frontend/taskdeck-web/src/main.ts Application entry point with router and Pinia setup
frontend/taskdeck-web/src/App.vue Root Vue component
frontend/taskdeck-web/src/router/index.ts Vue Router configuration with board routes
frontend/taskdeck-web/src/store/boardStore.ts Pinia store for board state management
frontend/taskdeck-web/src/api/*.ts API client modules for boards, columns, cards, and labels
frontend/taskdeck-web/src/types/board.ts TypeScript type definitions for domain models
frontend/taskdeck-web/src/views/*.vue Board list and detail view components
frontend/taskdeck-web/src/components/board/*.vue Column and card UI components
backend/tests//obj/ Build artifacts (should be in .gitignore)
backend/src/Taskdeck.Infrastructure/* Infrastructure layer with EF Core repositories

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +48 to +52
foreach (var labelId in dto.LabelIds.Where(validLabelIds.Contains))
{
var cardLabel = new CardLabel(card.Id, labelId);
card.AddLabel(cardLabel);
}
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.

Suggested change
foreach (var labelId in dto.LabelIds.Where(validLabelIds.Contains))
{
var cardLabel = new CardLabel(card.Id, labelId);
card.AddLabel(cardLabel);
}
dto.LabelIds
.Where(validLabelIds.Contains)
.Select(labelId => new CardLabel(card.Id, labelId))
.ToList()
.ForEach(cardLabel => card.AddLabel(cardLabel));

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +98
foreach (var labelId in dto.LabelIds.Where(validLabelIds.Contains))
{
var cardLabel = new CardLabel(card.Id, labelId);
card.AddLabel(cardLabel);
}
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.

Suggested change
foreach (var labelId in dto.LabelIds.Where(validLabelIds.Contains))
{
var cardLabel = new CardLabel(card.Id, labelId);
card.AddLabel(cardLabel);
}
dto.LabelIds
.Where(validLabelIds.Contains)
.Select(labelId => new CardLabel(card.Id, labelId))
.ToList()
.ForEach(cardLabel => card.AddLabel(cardLabel));

Copilot uses AI. Check for mistakes.

if (columnId.HasValue)
{
query = query.Where(c => c.ColumnId == columnId.Value);
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable columnId may be null at this access because it has a nullable type.

Copilot uses AI. Check for mistakes.

if (labelId.HasValue)
{
query = query.Where(c => c.CardLabels.Any(cl => cl.LabelId == labelId.Value));
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable labelId may be null at this access because it has a nullable type.

Copilot uses AI. Check for mistakes.
@Chris0Jeky Chris0Jeky merged commit 29d9abd into main Nov 18, 2025
7 checks passed
@Chris0Jeky Chris0Jeky deleted the claude/create-feature-f-01QrRAsJ4S14advmNnQhp2La branch November 18, 2025 03:44
Chris0Jeky added a commit that referenced this pull request Feb 16, 2026
…J4S14advmNnQhp2La

Claude/create feature f 01 qr r as j4 s14advm nn qhp2 la
Chris0Jeky added a commit that referenced this pull request Mar 29, 2026
…lean up tests

- Use finally block to always reset lifecycleActionInProgress (Major #1)
- Fix misleading "single assignment" comment in boardCrudStore (Minor #5)
- Remove redundant test with no meaningful assertions (Minor #3)
- Rename resolveDelete to resolvePush for clarity (Minor #4)
Chris0Jeky added a commit that referenced this pull request Mar 29, 2026
* Fix archive board freeze by navigating before clearing state

Navigate to /boards before calling boardStore.deleteBoard so the
BoardView is unmounted and its reactive subscriptions (sortedColumns,
cardsByColumn, filter computeds) are torn down before the sequential
state mutations fire.  This eliminates the ~30-second browser freeze
caused by cascading re-renders while the view was still mounted.

Add loading state to the lifecycle action button to provide immediate
feedback and prevent double-clicks.

Fixes #519

* Clear board detail state before filtering boards list in deleteBoard

Reorder state mutations in deleteBoard so detail refs (currentBoard,
cards, labels, comments, presence) are cleared before the boards array
is filtered.  This prevents downstream watchers on `boards` from
reading stale detail state during the reactive flush.

* Add tests for archive navigation order and loading state

Verify that router.push fires before boardStore.deleteBoard to prevent
reactive cascade freeze.  Add tests for the disabled/loading button
label during the archive action.

* Address review findings: use finally block, fix misleading comment, clean up tests

- Use finally block to always reset lifecycleActionInProgress (Major #1)
- Fix misleading "single assignment" comment in boardCrudStore (Minor #5)
- Remove redundant test with no meaningful assertions (Minor #3)
- Rename resolveDelete to resolvePush for clarity (Minor #4)
Chris0Jeky added a commit that referenced this pull request Apr 9, 2026
CreateForLinking now requires initiatingUserId parameter, stored in
UserId field. This prevents CSRF attacks where an attacker generates
a link code and tricks a victim into exchanging it, linking the
attacker's GitHub to the victim's account.

Addresses adversarial review finding #1 (CRITICAL).
Chris0Jeky added a commit that referenced this pull request Apr 9, 2026
- GitHubLogin requires authentication for mode=link and stores caller
  userId in OAuth state for CSRF protection
- GitHubCallback reads mode only from tamper-proof OAuth state, never
  from query string
- ExchangeCode re-issues fresh JWT at exchange time instead of reading
  stored token from DB (no plaintext JWT in database)
- LinkGitHub verifies link code was initiated by the same user who is
  exchanging it (CSRF protection)
- All failure paths use uniform error messages to prevent timing
  side-channel enumeration

Addresses findings #1, #3, #5, #7, #8 (CRITICAL/HIGH/MEDIUM).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants