Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 272 additions & 0 deletions .kiro/specs/frontend-tags-implementation/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
# Design Document

## Overview

The tags implementation follows the hexagonal architecture pattern established in the subscribers module, ensuring consistency and maintainability across the codebase. The design implements a complete CRUD system for tag management with proper separation of concerns across domain, application, and infrastructure layers.

The implementation leverages the existing Tag domain model and extends it with the full architecture stack including repositories, use cases, API integration, state management, and Vue.js components.

## Architecture

The tags module follows the same hexagonal architecture as subscribers:

```text
src/tag/
├── domain/ # Business logic and entities
│ ├── models/ # Domain models and types
│ ├── repositories/ # Repository interfaces
│ └── usecases/ # Business use cases
├── application/ # Application services
│ └── composables/ # Vue composables
├── infrastructure/ # External concerns
│ ├── api/ # HTTP API implementations
│ ├── di/ # Dependency injection
│ ├── store/ # Pinia state management
│ └── views/ # Vue components and pages
├── __tests__/ # Module-level tests
├── di.ts # DI re-export
└── index.ts # Public API
```

### Layer Responsibilities

- **Domain Layer**: Contains business entities (Tag), repository interfaces, and use cases
- **Application Layer**: Provides composables that orchestrate domain use cases
- **Infrastructure Layer**: Implements external concerns (API, store, UI components)

## Components and Interfaces

### Domain Layer

#### Models

- **Tag**: Domain model with id (UUID v4), name, color, subscribers, timestamps
- **TagResponse**: API response type for tag data
- **TagColors**: Enum for available tag colors
- **Schemas**: Zod validation schemas for tag data, including UUID validation

#### Repository Interface

```typescript
interface TagRepository {
findAll(): Promise<Tag[]>
findById(id: string): Promise<Tag | null>
create(tag: Omit<Tag, 'id' | 'createdAt' | 'updatedAt'>): Promise<Tag>
update(id: string, tag: Partial<Tag>): Promise<Tag>
delete(id: string): Promise<void>
}
```

#### Use Cases

- **FetchTags**: Retrieve all tags with optional filtering
- **CreateTag**: Create a new tag with validation (Zod, UUID, name uniqueness)
- **UpdateTag**: Update existing tag with validation
- **DeleteTag**: Remove a tag from the system

### Application Layer

#### Composables

- **useTags**: Main composable providing reactive tag management functionality
- Exposes tag list, loading states, error handling
- Provides methods for CRUD operations
- Manages local state and API interactions

### Infrastructure Layer

#### API Implementation

- **TagApi**: HTTP client for tag-related API calls
- Implements TagRepository interface
- Handles API errors and response transformation
- Uses existing HTTP client configuration
- All endpoints and models annotated with OpenAPI/Swagger

#### State Management

- **TagStore**: Pinia store for tag state management
- Manages tag list, loading states, and errors
- Provides actions for CRUD operations
- Integrates with use cases through dependency injection

#### Dependency Injection

- **Container**: DI container for tag dependencies
- **Initialization**: Module initialization functions
- **Configuration**: Setup for repository and use case instances

#### Views and Components

- **TagList**: Component for displaying list of tags
- **TagForm**: Component for creating/editing tags
- **TagItem**: Component for individual tag display
- **TagPage**: Main page component for tag management
- **DeleteConfirmation**: Modal for tag deletion confirmation

## Data Models

### Tag Entity

```typescript
class Tag {
id: string // UUID v4, validated
name: string
color: TagColors
subscribers: ReadonlyArray<string> | string
createdAt?: Date | string
updatedAt?: Date | string

// Methods
static fromResponse(response: TagResponse): Tag
get colorClass(): string
get subscriberCount(): number
}
```

### API Response Types

```typescript
interface TagResponse {
id: string // UUID v4
name: string
color: string
subscribers: ReadonlyArray<string> | string
createdAt?: string
updatedAt?: string
}

interface CreateTagRequest {
name: string
color: TagColors
}

interface UpdateTagRequest {
name?: string
color?: TagColors
}
```

### Store State

```typescript
interface TagStoreState {
tags: Tag[]
loading: LoadingStates
error: TagError | null
}

interface LoadingStates {
fetch: boolean
create: boolean
update: boolean
delete: boolean
}
```

## Validation

- All tag IDs are validated as UUID v4 (Zod schema)
- Tag names: required, max 50 chars, unique per workspace
- Tag color: required, from predefined palette or valid hex code
- All user input is validated before API calls

## Error Handling

### Error Types

- **TagApiError**: HTTP API errors with standardized structure `{ code, message, details }`
- **TagValidationError**: Client-side validation errors
- **TagNotFoundError**: Specific error for missing tags

### Error Handling Strategy

- API errors are caught and transformed into user-friendly messages (i18n keys)
- Validation errors are displayed inline in forms
- Network errors trigger retry mechanisms
- Global error handling through store error state

### Error Recovery

- Automatic retry for transient network errors
- Manual retry buttons for failed operations
- Optimistic updates with rollback on failure
- Clear error states after successful operations

## Internationalization (i18n)

- All user-facing text uses i18n keys (e.g., `tag.list.empty`, `tag.create.success`)
- Support for RTL languages and pluralization
- Locale-specific date formatting

## Security

- Input validation for all endpoints (UUID, name, color)
- Output encoding and sanitization for tag names
- CSRF protection for API calls
- OAuth2 authentication and RBAC enforced
- No sensitive data in logs

## Testing Strategy

### Unit Tests

- **Domain Models**: Test Tag class methods and validation
- **Use Cases**: Test business logic with mocked repositories
- **API Client**: Test HTTP interactions with mock responses
- **Store**: Test state mutations and actions

### Integration Tests

- **Component Integration**: Test component interactions with store
- **API Integration**: Test full API flow with test server
- **Module Integration**: Test complete tag workflows

### Architecture Tests

- **Isolation Tests**: Ensure proper layer separation
- **Dependency Tests**: Verify dependency injection configuration
- **Import Tests**: Validate clean architecture boundaries

### Test Structure

```text
__tests__/
├── architecture-isolation.test.ts
├── component-integration.test.ts
├── integration.test.ts
└── repository.mock.ts
```

### Testing Tools

- **Vitest**: Test runner and assertion library
- **@testing-library/vue**: Component testing utilities
- **MSW**: API mocking for integration tests
- **Test Containers**: For full integration testing

- All new logic must be covered by tests, with test names following the pattern `should do something when condition`.

## Implementation Considerations

### Performance

- Virtual scrolling for large tag lists
- Computed properties for filtered/sorted data
- Debounced search functionality
- Cache tag data with appropriate invalidation

### Accessibility

- ARIA labels for all interactive elements
- Keyboard navigation support
- Screen reader compatibility
- Color contrast compliance for tag colors

### Browser Compatibility

- Support for modern browsers (ES2020+)
- Graceful degradation for older browsers
- Progressive enhancement approach
- Polyfills where necessary

101 changes: 101 additions & 0 deletions .kiro/specs/frontend-tags-implementation/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Requirements Document

## Introduction

This feature implements a complete tags management system in the frontend following the same hexagonal architecture pattern used in the subscribers module. The implementation will provide full CRUD operations for tags, including listing, creating, updating, and deleting tags, with proper state management, API integration, and Vue.js components. The tags system will be integrated with the existing subscriber system to allow tagging of subscribers.

## Requirements

### Requirement 1

**User Story:** As a user, I want to view a list of all available tags so that I can see what tags exist in the system

#### Acceptance Criteria

1. WHEN the user navigates to the tags page THEN the system SHALL display a list of all existing tags
2. WHEN tags are loading THEN the system SHALL show a loading indicator
3. WHEN no tags exist THEN the system SHALL display an appropriate empty state message
4. WHEN tags fail to load THEN the system SHALL display an error message with retry option

### Requirement 2

**User Story:** As a user, I want to create new tags so that I can organize and categorize subscribers

#### Acceptance Criteria

1. WHEN the user clicks the create tag button THEN the system SHALL display a tag creation form with the following required fields: Name (required, max 50 characters, unique per workspace) and Color (required, predefined palette or valid hex code)
2. WHEN the user submits a valid tag form THEN the system SHALL create the tag and update the list
3. WHEN the user submits an invalid tag form THEN the system SHALL display validation errors, explicitly highlight invalid fields, and show validation messages
4. WHEN tag creation fails due to server or network error THEN the system SHALL display an error message
5. WHEN a tag is successfully created THEN the system SHALL show a success notification

### Requirement 3

**User Story:** As a user, I want to edit existing tags so that I can update tag information when needed

#### Acceptance Criteria

1. WHEN the user clicks edit on a tag THEN the system SHALL display an edit form with current tag data
2. WHEN the user submits valid changes THEN the system SHALL update the tag and refresh the list
3. WHEN the user submits invalid changes THEN the system SHALL display validation errors
4. WHEN tag update fails THEN the system SHALL display an error message
5. WHEN a tag is successfully updated THEN the system SHALL show a success notification

### Requirement 4

**User Story:** As a user, I want to delete tags so that I can remove tags that are no longer needed

#### Acceptance Criteria

1. WHEN the user clicks delete on a tag THEN the system SHALL show a confirmation dialog
2. WHEN the user confirms deletion THEN the system SHALL delete the tag and update the list
3. WHEN the user cancels deletion THEN the system SHALL close the dialog without changes
4. WHEN tag deletion fails THEN the system SHALL display an error message
5. WHEN a tag is successfully deleted THEN the system SHALL show a success notification

### Requirement 5

**User Story:** As a user, I want to see tag details including subscriber count so that I can understand tag usage

#### Acceptance Criteria

1. WHEN viewing the tag list THEN the system SHALL display tag name, color, and subscriber count
2. WHEN a tag has subscribers THEN the system SHALL show the correct count
3. WHEN a tag has no subscribers THEN the system SHALL show zero count
4. WHEN tag colors are displayed THEN the system SHALL use the appropriate CSS classes

### Requirement 6

**User Story:** As a developer, I want the tags module to follow the same architecture as subscribers so that the codebase remains consistent

#### Acceptance Criteria

1. WHEN implementing the tags module THEN the system SHALL use hexagonal architecture with domain, application, and infrastructure layers
2. WHEN implementing repositories THEN the system SHALL define interfaces in the domain layer and implementations in infrastructure
3. WHEN implementing use cases THEN the system SHALL place business logic in the domain layer
4. WHEN implementing API calls THEN the system SHALL place them in the infrastructure layer
5. WHEN implementing state management THEN the system SHALL use Pinia store in the infrastructure layer
6. WHEN implementing components THEN the system SHALL place them in the infrastructure/views layer

### Requirement 7

**User Story:** As a developer, I want proper dependency injection setup so that the module can be easily tested and maintained

#### Acceptance Criteria

1. WHEN the tags module is initialized THEN the system SHALL provide proper dependency injection configuration
2. WHEN dependencies are injected THEN the system SHALL use interfaces for loose coupling
3. WHEN the module is used THEN the system SHALL provide initialization functions similar to subscribers
4. WHEN testing THEN the system SHALL allow easy mocking of dependencies

### Requirement 8

**User Story:** As a developer, I want comprehensive test coverage so that the tags functionality is reliable

#### Acceptance Criteria

1. WHEN implementing domain models THEN the system SHALL include unit tests for Tag class
2. WHEN implementing use cases THEN the system SHALL include unit tests for business logic
3. WHEN implementing components THEN the system SHALL include integration tests
4. WHEN implementing the module THEN the system SHALL include architecture isolation tests
5. WHEN implementing repositories THEN the system SHALL provide mock implementations for testing
Loading
Loading