Claude/create feature f 01 qr r as j4 s14advm nn qhp2 la#1
Conversation
- 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!
There was a problem hiding this comment.
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.
| foreach (var labelId in dto.LabelIds.Where(validLabelIds.Contains)) | ||
| { | ||
| var cardLabel = new CardLabel(card.Id, labelId); | ||
| card.AddLabel(cardLabel); | ||
| } |
There was a problem hiding this comment.
This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.
| 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)); |
| foreach (var labelId in dto.LabelIds.Where(validLabelIds.Contains)) | ||
| { | ||
| var cardLabel = new CardLabel(card.Id, labelId); | ||
| card.AddLabel(cardLabel); | ||
| } |
There was a problem hiding this comment.
This foreach loop immediately maps its iteration variable to another variable - consider mapping the sequence explicitly using '.Select(...)'.
| 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)); |
…J4S14advmNnQhp2La Claude/create feature f 01 qr r as j4 s14advm nn qhp2 la
* 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)
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).
- 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).
No description provided.