Add complete solution: documentation, frontend, and project files
- Add comprehensive documentation in docs/ (architecture, features, roadmap) - Add german-app-frontend with Vite, TypeScript, ESLint configuration - Add AGENTS.md and .gitignore Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
d90e4792d6
commit
76e8af4987
32 changed files with 10866 additions and 0 deletions
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Create .gitignore (if not already present)
|
||||||
|
echo "# Dependencies
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Backend
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
*.cache
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
.coverage
|
||||||
|
" > .gitignore
|
||||||
534
AGENTS.md
Normal file
534
AGENTS.md
Normal file
|
|
@ -0,0 +1,534 @@
|
||||||
|
# DeutschLernen Solution Development Instructions
|
||||||
|
|
||||||
|
This file contains project-specific instructions, rules, and workflows for Mistral Vibe CLI when working on the **DeutschLernen** solution, which includes:
|
||||||
|
- **GermanApp** (Backend: ASP.NET Core Web API, .NET 9.0)
|
||||||
|
- **german-app-frontend** (Frontend: React 19, TypeScript, Vite)
|
||||||
|
|
||||||
|
This solution follows **Clean Architecture** principles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Solution Architecture: Clean Architecture
|
||||||
|
|
||||||
|
The solution is structured according to **Uncle Bob's Clean Architecture** principles with the following layers:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ PRESENTATION LAYER │
|
||||||
|
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
|
||||||
|
│ │ german-app-frontend │ │ GermanApp Controllers │ │
|
||||||
|
│ │ (React + TypeScript)│ │ (ASP.NET Core Minimal APIs)│ │
|
||||||
|
│ └─────────────────────┘ └───────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ APPLICATION LAYER │
|
||||||
|
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Use Cases, Application Services, DTOs, Command/Query │ │
|
||||||
|
│ │ - GermanApp/Application/ │ │
|
||||||
|
│ │ - MediatR pattern for CQRS (recommended) │ │
|
||||||
|
│ │ - Business logic orchestration │ │
|
||||||
|
│ └───────────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ DOMAIN LAYER │
|
||||||
|
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Core Business Logic, Entities, Value Objects, Domain │ │
|
||||||
|
│ │ Events, Domain Services │ │
|
||||||
|
│ │ - GermanApp/Domain/ │ │
|
||||||
|
│ │ - Pure C# (no framework dependencies) │ │
|
||||||
|
│ │ - Contains enterprise-wide business rules │ │
|
||||||
|
│ └───────────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ INFRASTRUCTURE LAYER │
|
||||||
|
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
|
||||||
|
│ │ Data Access │ │ External Services │ │
|
||||||
|
│ │ - Repositories │ │ - Email, SMS, Payments │ │
|
||||||
|
│ │ - Entity Framework │ │ - File Storage │ │
|
||||||
|
│ │ - DbContext │ │ - Caching │ │
|
||||||
|
│ └─────────────────────┘ └───────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### The Dependency Rule
|
||||||
|
**Inner layers MUST NOT depend on outer layers.** Dependencies flow INWARD:
|
||||||
|
- **Presentation** → **Application** → **Domain**
|
||||||
|
- **Infrastructure** → **Domain** (via interfaces defined in Domain/Application)
|
||||||
|
- **Infrastructure** → **Application** (implementations of interfaces)
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
1. **Single Responsibility**: Each class has one reason to change
|
||||||
|
2. **Open/Closed**: Open for extension, closed for modification
|
||||||
|
3. **Liskov Substitution**: Subtypes must be substitutable
|
||||||
|
4. **Interface Segregation**: Clients shouldn't depend on unused interfaces
|
||||||
|
5. **Dependency Inversion**: Depend on abstractions, not concretions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
### Backend: GermanApp (ASP.NET Core)
|
||||||
|
```
|
||||||
|
GermanApp/
|
||||||
|
├── Domain/ # Domain Layer (Pure C#)
|
||||||
|
│ ├── Entities/ # Business entities
|
||||||
|
│ ├── ValueObjects/ # Immutable value objects
|
||||||
|
│ ├── Enums/ # Domain enums
|
||||||
|
│ ├── Exceptions/ # Domain-specific exceptions
|
||||||
|
│ ├── Interfaces/ # Domain interfaces (repositories, services)
|
||||||
|
│ └── DomainEvents/ # Domain events
|
||||||
|
│
|
||||||
|
├── Application/ # Application Layer
|
||||||
|
│ ├── UseCases/ # Use case handlers (CQRS pattern)
|
||||||
|
│ │ ├── Commands/ # Command handlers
|
||||||
|
│ │ └── Queries/ # Query handlers
|
||||||
|
│ ├── DTOs/ # Data Transfer Objects
|
||||||
|
│ ├── Interfaces/ # Application service interfaces
|
||||||
|
│ └── Services/ # Application services
|
||||||
|
│
|
||||||
|
├── Infrastructure/ # Infrastructure Layer
|
||||||
|
│ ├── Data/ # Data persistence
|
||||||
|
│ │ ├── Repositories/ # Repository implementations
|
||||||
|
│ │ └── DbContext/ # Entity Framework context
|
||||||
|
│ ├── Services/ # External service implementations
|
||||||
|
│ └── Configurations/ # Dependency injection configs
|
||||||
|
│
|
||||||
|
├── Presentation/ # Presentation Layer
|
||||||
|
│ ├── Controllers/ # API Controllers
|
||||||
|
│ ├── Endpoints/ # Minimal API endpoints
|
||||||
|
│ └── Models/ # API request/response models
|
||||||
|
│
|
||||||
|
├── Shared/ # Shared utilities
|
||||||
|
│ ├── Constants/ # Application constants
|
||||||
|
│ ├── Extensions/ # Extension methods
|
||||||
|
│ └── Helpers/ # Helper classes
|
||||||
|
│
|
||||||
|
├── Program.cs # Application entry point
|
||||||
|
├── appsettings.json # Configuration
|
||||||
|
└── Tests/ # Test projects
|
||||||
|
├── Unit/
|
||||||
|
│ ├── Domain/
|
||||||
|
│ ├── Application/
|
||||||
|
│ └── Infrastructure/
|
||||||
|
└── Integration/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend: german-app-frontend (React + TypeScript)
|
||||||
|
```
|
||||||
|
german-app-frontend/
|
||||||
|
├── public/ # Static files
|
||||||
|
├── src/
|
||||||
|
│ ├── assets/ # Static assets (images, fonts)
|
||||||
|
│ ├── components/ # React components
|
||||||
|
│ │ ├── ui/ # Reusable UI components
|
||||||
|
│ │ ├── layout/ # Layout components
|
||||||
|
│ │ └── features/ # Feature-specific components
|
||||||
|
│ │
|
||||||
|
│ ├── hooks/ # Custom React hooks
|
||||||
|
│ ├── lib/ # Utility functions, constants
|
||||||
|
│ │ └── api/ # API client, service calls
|
||||||
|
│ │
|
||||||
|
│ ├── stores/ # State management
|
||||||
|
│ ├── types/ # TypeScript type definitions
|
||||||
|
│ │ └── api/ # API types (mirror backend DTOs)
|
||||||
|
│ │
|
||||||
|
│ ├── pages/ # Page components
|
||||||
|
│ ├── routes/ # Routing configuration
|
||||||
|
│ │
|
||||||
|
│ ├── styles/ # Global styles, themes
|
||||||
|
│ │
|
||||||
|
│ ├── App.tsx # Main application component
|
||||||
|
│ └── main.tsx # Application entry point
|
||||||
|
│
|
||||||
|
├── package.json
|
||||||
|
└── tsconfig.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Style & Conventions
|
||||||
|
|
||||||
|
### Backend (C#)
|
||||||
|
|
||||||
|
#### General C# Standards
|
||||||
|
- Use **PascalCase** for all public types, methods, properties, and constants
|
||||||
|
- Use **camelCase** for local variables, method parameters, and private fields
|
||||||
|
- Use **_camelCase** with underscore prefix for private fields
|
||||||
|
- Use **UPPER_SNAKE_CASE** for constants
|
||||||
|
|
||||||
|
#### Formatting
|
||||||
|
- 4 spaces for indentation (no tabs)
|
||||||
|
- Opening braces on the same line (K&R style)
|
||||||
|
- One blank line between methods
|
||||||
|
- Line length: Keep under 120 characters when practical
|
||||||
|
|
||||||
|
#### Naming Conventions
|
||||||
|
- **Interfaces**: Prefix with `I` (e.g., `IUserRepository`, `IEmailService`)
|
||||||
|
- **Async methods**: Suffix with `Async`
|
||||||
|
- **Records**: Use PascalCase for properties
|
||||||
|
- **Boolean properties**: Prefix with `Is`, `Has`, `Can`, or `Should`
|
||||||
|
- **Domain entities**: Use business terminology (e.g., `Lesson`, `VocabularyWord`)
|
||||||
|
- **Value objects**: Use descriptive names (e.g., `EmailAddress`, `GermanWord`)
|
||||||
|
|
||||||
|
#### Clean Architecture Specific
|
||||||
|
- **Domain Layer**: Pure C# with NO framework dependencies
|
||||||
|
- No `using Microsoft.AspNetCore...`
|
||||||
|
- No `using System.Web...`
|
||||||
|
- Only primitive types or other domain types
|
||||||
|
- **Interfaces in Domain/Application**: Define interfaces where they are USED
|
||||||
|
- **Implementations in Infrastructure**: Implement interfaces defined in inner layers
|
||||||
|
- **DTOs**: Use `Record` types for immutable DTOs
|
||||||
|
- **Entities**: Use classes with private setters for mutable entities
|
||||||
|
|
||||||
|
#### .NET Specific
|
||||||
|
- Use **nullable reference types** (enabled in project)
|
||||||
|
- Prefer **records** over classes for DTOs and immutable data
|
||||||
|
- Use **Minimal APIs** style for simple endpoints
|
||||||
|
- Use **explicit typing** for public APIs, **var** for local variables
|
||||||
|
- Use **File-scoped namespaces**
|
||||||
|
|
||||||
|
### Frontend (TypeScript/React)
|
||||||
|
|
||||||
|
#### TypeScript
|
||||||
|
- Use **PascalCase** for types, interfaces, classes
|
||||||
|
- Use **camelCase** for variables, functions, properties
|
||||||
|
- Use **SCREAMING_SNAKE_CASE** for constants
|
||||||
|
- Use **ISomething** prefix for interfaces (optional but consistent)
|
||||||
|
|
||||||
|
#### React
|
||||||
|
- **Components**: PascalCase (e.g., `UserCard`, `LessonList`)
|
||||||
|
- **Hooks**: Use `use` prefix (e.g., `useUser`, `useLessons`)
|
||||||
|
- **Props**: Use TypeScript interfaces for prop types
|
||||||
|
- **Events**: Use `on` prefix for event handlers (e.g., `onClick`, `onSubmit`)
|
||||||
|
|
||||||
|
#### File Naming
|
||||||
|
- Components: `ComponentName.tsx`
|
||||||
|
- Hooks: `useHookName.ts`
|
||||||
|
- Utilities: `utilityName.ts`
|
||||||
|
- Types: `types.ts` or `TypeName.ts`
|
||||||
|
- Constants: `constants.ts`
|
||||||
|
|
||||||
|
#### API Client
|
||||||
|
- Use **axios** or **fetch** with a centralized API client
|
||||||
|
- Mirror backend DTO types in `src/types/api/`
|
||||||
|
- Use consistent naming: `getUser`, `createLesson`, `updateVocabularyWord`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing Requirements
|
||||||
|
|
||||||
|
### Backend (MsTest)
|
||||||
|
- **Framework**: MsTest (required)
|
||||||
|
- **Coverage**: All business logic must have unit tests
|
||||||
|
- **Integration tests**: For API endpoints and database interactions
|
||||||
|
|
||||||
|
#### Test Structure
|
||||||
|
```
|
||||||
|
Tests/
|
||||||
|
├── Unit/
|
||||||
|
│ ├── Domain/
|
||||||
|
│ │ └── Entities/
|
||||||
|
│ │ └── UserTests.cs
|
||||||
|
│ ├── Application/
|
||||||
|
│ │ └── UseCases/
|
||||||
|
│ │ └── CreateUserCommandHandlerTests.cs
|
||||||
|
│ └── Infrastructure/
|
||||||
|
│ └── Repositories/
|
||||||
|
│ └── UserRepositoryTests.cs
|
||||||
|
│
|
||||||
|
└── Integration/
|
||||||
|
├── Api/
|
||||||
|
│ └── WeatherForecastEndpointTests.cs
|
||||||
|
└── Database/
|
||||||
|
└── UserRepositoryIntegrationTests.cs
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Test Naming (Backend)
|
||||||
|
- Test classes: `[ClassUnderTest]Tests`
|
||||||
|
- Test methods: `MethodName_Scenario_ExpectedBehavior`
|
||||||
|
|
||||||
|
### Frontend (Vitest)
|
||||||
|
- **Framework**: Vitest (recommended for Vite projects)
|
||||||
|
- **Component tests**: Test user interactions and rendering
|
||||||
|
- **Unit tests**: Test utility functions and hooks
|
||||||
|
|
||||||
|
#### Test Naming (Frontend)
|
||||||
|
- Test files: `*.test.tsx` or `*.test.ts`
|
||||||
|
- Test blocks: `describe('ComponentName', () => {...})`
|
||||||
|
- Test cases: `it('should do something when condition', () => {...})`
|
||||||
|
|
||||||
|
### Test Quality (Both)
|
||||||
|
- Follow Arrange-Act-Assert pattern
|
||||||
|
- Each test should test ONE thing
|
||||||
|
- Use meaningful test data, not magic numbers/strings
|
||||||
|
- Mock external dependencies (API calls, database, etc.)
|
||||||
|
- Keep tests fast and isolated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Git Workflow
|
||||||
|
|
||||||
|
### Branching Strategy: GitHub Flow
|
||||||
|
1. **main** - Production-ready code (protected)
|
||||||
|
2. **feature/*** - Feature branches created from main
|
||||||
|
3. **bugfix/*** - Bug fix branches created from main
|
||||||
|
4. **refactor/*** - Refactoring branches
|
||||||
|
|
||||||
|
### Branch Naming
|
||||||
|
- `feature/[short-description]` - e.g., `feature/add-user-authentication`
|
||||||
|
- `bugfix/[short-description]` - e.g., `bugfix/lesson-load-error`
|
||||||
|
- `refactor/[short-description]` - e.g., `refactor/domain-entities`
|
||||||
|
- `docs/[short-description]` - For documentation changes
|
||||||
|
- Use kebab-case (lowercase with hyphens)
|
||||||
|
|
||||||
|
### Commit Conventions: Conventional Commits
|
||||||
|
```
|
||||||
|
type(scope): description
|
||||||
|
```
|
||||||
|
|
||||||
|
**Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `perf`
|
||||||
|
|
||||||
|
**Scope**: Should indicate the layer or project:
|
||||||
|
- `feat(backend):` or `feat(domain):` or `feat(api):`
|
||||||
|
- `feat(frontend):` or `feat(ui):`
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```
|
||||||
|
feat(backend/domain): add User entity with validation
|
||||||
|
feat(frontend/ui): create LessonCard component
|
||||||
|
fix(backend/api): handle null values in weather endpoint
|
||||||
|
refactor(backend/application): extract user creation use case
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pull Requests
|
||||||
|
- All changes must go through a Pull Request
|
||||||
|
- PR title should follow Conventional Commits format
|
||||||
|
- PR description should include:
|
||||||
|
- What changed
|
||||||
|
- Why it changed
|
||||||
|
- Screenshots/GIFs for UI changes
|
||||||
|
- Which Clean Architecture layer(s) were affected
|
||||||
|
- Minimum 1 approval required
|
||||||
|
- All CI checks must pass before merging
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Backend Commands
|
||||||
|
```bash
|
||||||
|
# Build
|
||||||
|
dotnet build
|
||||||
|
|
||||||
|
# Run
|
||||||
|
dotnet run --project GermanApp
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
dotnet test
|
||||||
|
dotnet test /p:CollectCoverage=true
|
||||||
|
|
||||||
|
# Add package
|
||||||
|
dotnet add GermanApp package PackageName
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend Commands
|
||||||
|
```bash
|
||||||
|
# Install
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Dev server
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Build
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Lint
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
npm run test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Before Pushing
|
||||||
|
1. Run all tests (backend and frontend)
|
||||||
|
2. Check for lint/warnings
|
||||||
|
3. Review changes: `git diff main`
|
||||||
|
4. Ensure no Clean Architecture violations
|
||||||
|
5. Squash commits if needed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Clean Architecture Implementation Guidelines
|
||||||
|
|
||||||
|
### Domain Layer (Pure C#)
|
||||||
|
- **NO** framework dependencies
|
||||||
|
- Contains: Entities, Value Objects, Domain Events, Domain Services, Interfaces
|
||||||
|
- Entities should have identity (Id) and business behavior
|
||||||
|
- Value Objects should be immutable
|
||||||
|
|
||||||
|
### Application Layer
|
||||||
|
- Contains: Use Cases, DTOs, Application Services, Interfaces
|
||||||
|
- Orchestrates domain objects to fulfill use cases
|
||||||
|
- Defines interfaces for infrastructure (repositories, services)
|
||||||
|
- Uses MediatR pattern for CQRS (recommended)
|
||||||
|
|
||||||
|
### Infrastructure Layer
|
||||||
|
- Contains: Repository implementations, DbContext, External services
|
||||||
|
- Implements interfaces defined in Domain/Application layers
|
||||||
|
- Entity Framework Core for data access
|
||||||
|
- External service adapters (email, file storage, etc.)
|
||||||
|
|
||||||
|
### Presentation Layer
|
||||||
|
- **Backend**: Minimal APIs, Controllers, API Models
|
||||||
|
- **Frontend**: React components, hooks, state management
|
||||||
|
- Thin layer that handles presentation concerns only
|
||||||
|
- Delegates business logic to Application layer
|
||||||
|
|
||||||
|
### Dependency Injection Setup
|
||||||
|
```csharp
|
||||||
|
// In Program.cs
|
||||||
|
|
||||||
|
// Domain layer - no registration needed (pure logic)
|
||||||
|
|
||||||
|
// Application layer
|
||||||
|
builder.Services.AddApplicationServices();
|
||||||
|
|
||||||
|
// Infrastructure layer
|
||||||
|
builder.Services.AddInfrastructureServices(configuration);
|
||||||
|
|
||||||
|
// Presentation layer
|
||||||
|
builder.Services.AddPresentationServices();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cross-Cutting Concerns
|
||||||
|
|
||||||
|
### API Contracts
|
||||||
|
- **Backend**: Define API models in Presentation/Models
|
||||||
|
- **Frontend**: Mirror these types in src/types/api/
|
||||||
|
- Keep API contracts stable and versioned
|
||||||
|
- Use DTOs for all API communication (never domain entities directly)
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
- **Domain**: Throw domain-specific exceptions
|
||||||
|
- **Application**: Handle domain exceptions, map to application errors
|
||||||
|
- **Presentation**: Map to appropriate HTTP status codes
|
||||||
|
- **Frontend**: Display user-friendly error messages
|
||||||
|
|
||||||
|
### Validation
|
||||||
|
- **Domain**: Entity/Value Object validation (business rules)
|
||||||
|
- **Application**: Use case validation (cross-entity rules)
|
||||||
|
- **Presentation**: Request model validation (FluentValidation)
|
||||||
|
- **Frontend**: Client-side validation (Zod, Yup, or similar)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Implementation & Tracking
|
||||||
|
|
||||||
|
For complex features, use the **Feature Tracking System** in `docs/features/`:
|
||||||
|
|
||||||
|
### Feature Documentation Structure
|
||||||
|
```
|
||||||
|
docs/features/
|
||||||
|
├── README.md # Feature tracking overview & workflow
|
||||||
|
├── template.md # Template for new feature implementation plans
|
||||||
|
└── [feature-name].md # Individual feature files with:
|
||||||
|
# - Status (Planned/In Progress/Code Review/Completed)
|
||||||
|
# - Priority & Complexity
|
||||||
|
# - Requirements & Technical Design
|
||||||
|
# - Implementation Plan & Tasks
|
||||||
|
# - Dependencies & Notes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Workflow
|
||||||
|
1. **Create**: Copy `template.md` → `[feature-name].md`, fill in details
|
||||||
|
2. **Plan**: Set status to `⏳ Planned`, add to `README.md` table
|
||||||
|
3. **Develop**: Update status to `🚀 In Progress`, check off tasks
|
||||||
|
4. **Review**: Set status to `🔄 Code Review`, link PR in feature file
|
||||||
|
5. **Complete**: Set status to `✅ Completed`, document lessons learned
|
||||||
|
|
||||||
|
### Status Icons
|
||||||
|
- ⏳ Planned - Feature defined, not started
|
||||||
|
- 🚀 In Progress - Actively being developed
|
||||||
|
- 🔄 Code Review - PR submitted, awaiting review
|
||||||
|
- ✅ Completed - Feature done and deployed
|
||||||
|
- ❌ Blocked - Cannot proceed due to dependencies
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
- Create a feature file **before** starting development
|
||||||
|
- Update the file **as you work** (tasks, notes, decisions)
|
||||||
|
- Be **specific** with tasks (not "implement X", but "create Y service", "add Z endpoint")
|
||||||
|
- Document **design decisions** and **lessons learned**
|
||||||
|
- Link to **PRs, commits, and code** in the feature file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- **Clean Architecture is mandatory**: Always check dependencies flow inward
|
||||||
|
- **MsTest required for backend**: All changes must include tests
|
||||||
|
- **Conventional Commits**: Follow strictly for all commits
|
||||||
|
- **Automatic deployment**: Merging to main deploys to production
|
||||||
|
- **Cross-project consistency**: Keep frontend and backend in sync
|
||||||
|
- **Feature tracking**: Use `docs/features/` for complex features
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: May 31, 2025*
|
||||||
|
*This file can be updated as project conventions evolve.*
|
||||||
|
rn new User
|
||||||
|
{
|
||||||
|
Username = username,
|
||||||
|
Email = email,
|
||||||
|
CreatedAt = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Domain behavior
|
||||||
|
public void ChangeEmail(Email newEmail)
|
||||||
|
{
|
||||||
|
Email = newEmail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Value Object Example
|
||||||
|
```csharp
|
||||||
|
namespace GermanApp.Domain.ValueObjects;
|
||||||
|
|
||||||
|
public record Email
|
||||||
|
{
|
||||||
|
public string Value { get; }
|
||||||
|
|
||||||
|
public Email(string value)
|
||||||
|
{
|
||||||
|
if (!IsValid(value))
|
||||||
|
throw new DomainException("Invalid email format");
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValid(string email)
|
||||||
|
{
|
||||||
|
// Validation logic
|
||||||
|
return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"); }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- **Clean Architecture is mandatory**: Always check dependencies flow inward
|
||||||
|
- **MsTest required for backend**: All changes must include tests
|
||||||
|
- **Conventional Commits**: Follow strictly for all commits
|
||||||
|
- **Automatic deployment**: Merging to main deploys to production
|
||||||
|
- **Cross-project consistency**: Keep frontend and backend in sync
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: May 31, 2025*
|
||||||
|
*This file can be updated as project conventions evolve.*
|
||||||
98
docs/README.md
Normal file
98
docs/README.md
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
# DeutschLernen Documentation
|
||||||
|
|
||||||
|
Welcome to the documentation for the **DeutschLernen** solution. This directory contains all project documentation organized by category.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Documentation Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
docs/
|
||||||
|
├── README.md # This file - Table of Contents
|
||||||
|
│
|
||||||
|
├── architecture/ # System architecture & design
|
||||||
|
│ ├── application-plan.md # High-level application plan and vision
|
||||||
|
│ ├── backend-structure.md # Backend architecture and component structure
|
||||||
|
│ └── frontend-structure.md # Frontend architecture and component structure
|
||||||
|
│
|
||||||
|
├── database/ # Database-related documentation
|
||||||
|
│ └── initial-database-schema.sql # Initial SQL schema for the database
|
||||||
|
│
|
||||||
|
└── development/ # Development guides & setup
|
||||||
|
└── how-to-run-vibe.md # Guide for running Vibe CLI in this project
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 Documentation Categories
|
||||||
|
|
||||||
|
### Architecture 🏗️
|
||||||
|
|
||||||
|
| File | Description | Last Updated |
|
||||||
|
|------|-------------|---------------|
|
||||||
|
| [application-plan.md](./architecture/application-plan.md) | Overall application vision, features, and roadmap | - |
|
||||||
|
| [backend-structure.md](./architecture/backend-structure.md) | Backend architecture, Clean Architecture layers, component diagrams | - |
|
||||||
|
| [frontend-structure.md](./architecture/frontend-structure.md) | Frontend architecture, React component structure, state management | - |
|
||||||
|
|
||||||
|
### Database 🗃️
|
||||||
|
|
||||||
|
| File | Description | Last Updated |
|
||||||
|
|------|-------------|---------------|
|
||||||
|
| [initial-database-schema.sql](./database/initial-database-schema.sql) | SQL schema for database initialization, tables, relationships | - |
|
||||||
|
|
||||||
|
### Development 🛠️
|
||||||
|
|
||||||
|
| File | Description | Last Updated |
|
||||||
|
|------|-------------|---------------|
|
||||||
|
| [how-to-run-vibe.md](./development/how-to-run-vibe.md) | Instructions for setting up and using Vibe CLI with this project | - |
|
||||||
|
|
||||||
|
### Feature Tracking
|
||||||
|
| File | Description | Last Updated |
|
||||||
|
|------|-------------|---------------|
|
||||||
|
| [features/README.md](./features/README.md) | Feature implementation plans and progress tracking | - |
|
||||||
|
| [features/template.md](./features/template.md) | Template for creating new feature plans | - |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Adding New Documentation
|
||||||
|
|
||||||
|
When adding new documentation files, please follow these guidelines:
|
||||||
|
|
||||||
|
1. **Choose the right category**: Place files in the appropriate subdirectory
|
||||||
|
2. **Use kebab-case naming**: `new-document.md` not `NewDocument.md`
|
||||||
|
3. **Update this README**: Add your file to the appropriate table above
|
||||||
|
4. **Keep it organized**: Create new subdirectories if a category grows too large
|
||||||
|
|
||||||
|
### Suggested Categories
|
||||||
|
|
||||||
|
- `architecture/` - System design, component diagrams, technical decisions
|
||||||
|
- `database/` - Schema, migrations, data models
|
||||||
|
- `development/` - Setup guides, development workflows, tooling
|
||||||
|
- `api/` - API documentation, endpoints, contracts (if not using Swagger)
|
||||||
|
- `testing/` - Test strategies, test data, test cases
|
||||||
|
- `deployment/` - Deployment guides, CI/CD, infrastructure
|
||||||
|
- `features/` - Feature specifications, user stories
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Quick Links
|
||||||
|
|
||||||
|
- **[Application Plan](./architecture/application-plan.md)** - Start here for project vision
|
||||||
|
- **[Backend Structure](./architecture/backend-structure.md)** - Clean Architecture implementation
|
||||||
|
- **[Database Schema](./database/initial-database-schema.sql)** - Database design
|
||||||
|
- **[Vibe Setup](./development/how-to-run-vibe.md)** - Development environment setup
|
||||||
|
- **[Feature Tracking](./features/README.md)** - Feature implementation plans & progress
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Tips
|
||||||
|
|
||||||
|
- Use the search functionality in your code editor to find specific topics across all docs
|
||||||
|
- Documentation should be **just enough** - focus on the "why" not just the "what"
|
||||||
|
- Keep documentation **up to date** with code changes
|
||||||
|
- For API documentation, rely on **Swagger/OpenAPI** where possible
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: May 31, 2025*
|
||||||
|
*Need help? Check the [AGENTS.md](../AGENTS.md) file for development rules and workflows*
|
||||||
546
docs/ROADMAP.md
Normal file
546
docs/ROADMAP.md
Normal file
|
|
@ -0,0 +1,546 @@
|
||||||
|
# DeutschLernen Development Roadmap
|
||||||
|
|
||||||
|
This document provides a comprehensive **development roadmap** for the DeutschLernen project, based on the feature plans in `docs/features/`. It outlines the implementation phases, timelines, resource allocation, and milestones for delivering the complete German learning application.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Project Overview
|
||||||
|
|
||||||
|
**DeutschLernen** is a comprehensive German language learning web application with:
|
||||||
|
- Structured lessons following CEFR levels (A1-C1)
|
||||||
|
- AI-powered features (story generation, speech recognition, text-to-speech)
|
||||||
|
- Interactive exercises and quizzes
|
||||||
|
- Gamification (points, badges, streaks)
|
||||||
|
- Progress tracking and analytics
|
||||||
|
|
||||||
|
**Target Users:** Self-learners of German at all levels (A1–C1)
|
||||||
|
|
||||||
|
**Technology Stack:** .NET 9.0 (Backend) + React 19 + TypeScript (Frontend) + PostgreSQL + AI Services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗺️ Implementation Phases
|
||||||
|
|
||||||
|
The project is divided into **4 phases** based on dependencies and priority:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Foundation 🏗️
|
||||||
|
**Duration:** 2 weeks | **Total Hours:** 30-42h | **Priority:** Critical
|
||||||
|
|
||||||
|
### Objective
|
||||||
|
Establish the technical foundation for the entire application, including backend project, database, and authentication system.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
| # | Feature | Description | Hours | Status | Dependencies |
|
||||||
|
|---|---------|-------------|-------|--------|--------------|
|
||||||
|
| 1.1 | [Infrastructure Setup](features/infrastructure-setup.md) | .NET project, PostgreSQL, Docker, CI/CD | 10-14h | ⏳ Planned | None |
|
||||||
|
| 1.2 | [User Authentication](features/user-authentication.md) | JWT-based auth with ASP.NET Core Identity | 4-6h | ⏳ Planned | 1.1 |
|
||||||
|
|
||||||
|
### Deliverables
|
||||||
|
- ✅ Working .NET 9.0 backend project
|
||||||
|
- ✅ PostgreSQL database with schema
|
||||||
|
- ✅ Docker containers for all services
|
||||||
|
- ✅ GitHub Actions CI/CD pipeline
|
||||||
|
- ✅ Authentication endpoints (register, login, logout)
|
||||||
|
- ✅ JWT token generation and validation
|
||||||
|
- ✅ Development environment setup guide
|
||||||
|
|
||||||
|
### Success Criteria
|
||||||
|
- Backend project builds and runs successfully
|
||||||
|
- Database is accessible and migrations work
|
||||||
|
- Docker Compose spins up all services
|
||||||
|
- CI/CD pipeline passes on push
|
||||||
|
- Authentication flow works end-to-end
|
||||||
|
|
||||||
|
### Week 1
|
||||||
|
| Day | Developer | Tasks | Hours |
|
||||||
|
|-----|-----------|-------|-------|
|
||||||
|
| 1 | Backend | Initialize .NET project, configure appsettings | 4 |
|
||||||
|
| 1 | Backend | Set up Swagger/OpenAPI, CORS, logging | 2 |
|
||||||
|
| 2 | Backend | Configure PostgreSQL, create initial schema | 3 |
|
||||||
|
| 2 | Backend | Set up EF Core, create first migration | 2 |
|
||||||
|
| 3 | Backend | Create Dockerfile for backend | 2 |
|
||||||
|
| 3 | DevOps | Create docker-compose.yml | 2 |
|
||||||
|
| 4 | Backend | Create GitHub Actions workflow | 3 |
|
||||||
|
| 4 | Backend | Test complete infrastructure | 2 |
|
||||||
|
| 5 | Backend | Start User Authentication feature | 4 |
|
||||||
|
|
||||||
|
### Week 2
|
||||||
|
| Day | Developer | Tasks | Hours |
|
||||||
|
|-----|-----------|-------|-------|
|
||||||
|
| 6 | Backend | Create User entity and DTOs | 3 |
|
||||||
|
| 6 | Backend | Configure ASP.NET Core Identity | 2 |
|
||||||
|
| 7 | Backend | Create AuthService with JWT | 3 |
|
||||||
|
| 7 | Backend | Create AuthController endpoints | 2 |
|
||||||
|
| 8 | Backend | Implement token validation middleware | 2 |
|
||||||
|
| 8 | Backend | Add authorization to endpoints | 2 |
|
||||||
|
| 9 | Backend | Write unit tests for AuthService | 2 |
|
||||||
|
| 9 | Backend | Write integration tests for AuthController | 2 |
|
||||||
|
| 10 | Backend | Test authentication flow end-to-end | 2 |
|
||||||
|
| 10 | Backend | Finalize and merge Phase 1 | 2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Core Backend 🎯
|
||||||
|
**Duration:** 2 weeks | **Total Hours:** 42-58h | **Priority:** Critical
|
||||||
|
|
||||||
|
### Objective
|
||||||
|
Implement the core backend functionality, including lesson management, AI services integration, vocabulary system, and quiz system.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
| # | Feature | Description | Hours | Status | Dependencies |
|
||||||
|
|---|---------|-------------|-------|--------|--------------|
|
||||||
|
| 2.1 | [Lesson Management](features/lesson-management.md) | Lessons, levels, progress tracking | 10-16h | ⏳ Planned | Phase 1 |
|
||||||
|
| 2.2 | [AI Services](features/ai-services.md) | Mistral, Vosk, Coqui TTS integration | 10-16h | ⏳ Planned | Phase 1 |
|
||||||
|
| 2.3 | [Vocabulary System](features/vocabulary-system.md) | Word storage, audio, import | 8-12h | ⏳ Planned | Phase 1, 2.1 |
|
||||||
|
| 2.4 | [Quiz System](features/quiz-system.md) | Multiple question types, scoring | 6-10h | ⏳ Planned | Phase 1, 2.1 |
|
||||||
|
|
||||||
|
### Deliverables
|
||||||
|
- ✅ Complete CEFR level and lesson management
|
||||||
|
- ✅ User progress tracking with sequential unlocking
|
||||||
|
- ✅ Mistral-Medium API integration for story generation
|
||||||
|
- ✅ Vosk speech recognition integration
|
||||||
|
- ✅ Coqui TTS integration for audio generation
|
||||||
|
- ✅ Vocabulary CRUD with article tracking
|
||||||
|
- ✅ Bulk vocabulary import from Goethe/DW
|
||||||
|
- ✅ Quiz CRUD with 4 question types
|
||||||
|
- ✅ Quiz scoring and pass/fail determination
|
||||||
|
- ✅ Progress tracking on quiz completion
|
||||||
|
|
||||||
|
### Success Criteria
|
||||||
|
- All lesson content can be managed
|
||||||
|
- AI services generate stories, recognize speech, and generate audio
|
||||||
|
- Vocabulary system with audio works end-to-end
|
||||||
|
- Quiz system with all question types works
|
||||||
|
- Progress tracking updates correctly
|
||||||
|
|
||||||
|
### Week 3
|
||||||
|
| Day | Developer | Tasks | Hours | Feature |
|
||||||
|
|-----|-----------|-------|-------|---------|
|
||||||
|
| 11 | Backend | Create Level/Lesson entities | 3 | 2.1 |
|
||||||
|
| 11 | Backend | Create UserProgress entity | 2 | 2.1 |
|
||||||
|
| 12 | Backend | Create repositories | 3 | 2.1 |
|
||||||
|
| 12 | Backend | Create services | 3 | 2.1 |
|
||||||
|
| 13 | Backend | Create controllers | 2 | 2.1 |
|
||||||
|
| 13 | Backend | Implement unlocking logic | 2 | 2.1 |
|
||||||
|
| 14 | Backend | Write tests for Lesson Mgmt | 3 | 2.1 |
|
||||||
|
| 14 | Backend | Start AI Services | 2 | 2.2 |
|
||||||
|
|
||||||
|
### Week 4
|
||||||
|
| Day | Developer | Tasks | Hours | Feature |
|
||||||
|
|-----|-----------|-------|-------|---------|
|
||||||
|
| 15 | Backend | Configure Mistral API client | 3 | 2.2 |
|
||||||
|
| 15 | Backend | Implement retry/rate limiting | 2 | 2.2 |
|
||||||
|
| 16 | Backend | Set up Vosk Python environment | 3 | 2.2 |
|
||||||
|
| 16 | Backend | Create VoskService | 3 | 2.2 |
|
||||||
|
| 17 | Backend | Set up Coqui TTS environment | 2 | 2.2 |
|
||||||
|
| 17 | Backend | Create TtsService | 3 | 2.2 |
|
||||||
|
| 18 | Backend | Create health checks | 2 | 2.2 |
|
||||||
|
| 18 | Backend | Test AI Services | 2 | 2.2 |
|
||||||
|
| 19 | Backend | Start Vocabulary System | 4 | 2.3 |
|
||||||
|
| 20 | Backend | Start Quiz System | 4 | 2.4 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: Content & Features 📚
|
||||||
|
**Duration:** 2 weeks | **Total Hours:** 30-42h | **Priority:** High
|
||||||
|
|
||||||
|
### Objective
|
||||||
|
Implement the content management features (story integration, gamification) that build on the core backend.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
| # | Feature | Description | Hours | Status | Dependencies |
|
||||||
|
|---|---------|-------------|-------|--------|--------------|
|
||||||
|
| 3.1 | [Story Integration](features/story-integration.md) | AI-generated stories with audio | 8-12h | ⏳ Planned | Phase 2 |
|
||||||
|
| 3.2 | [Gamification](features/gamification.md) | Points, badges, streaks | 6-8h | ⏳ Planned | Phase 2 |
|
||||||
|
|
||||||
|
### Deliverables
|
||||||
|
- ✅ Story generation per level using Mistral
|
||||||
|
- ✅ Story segmentation per lesson
|
||||||
|
- ✅ Story audio generation using Coqui TTS
|
||||||
|
- ✅ Sequential story unlocking with lesson completion
|
||||||
|
- ✅ Word click-to-translate functionality
|
||||||
|
- ✅ Points system for lessons and quizzes
|
||||||
|
- ✅ Badge system with automatic awarding
|
||||||
|
- ✅ Daily streak tracking
|
||||||
|
- ✅ User dashboard with gamification display
|
||||||
|
|
||||||
|
### Success Criteria
|
||||||
|
- Stories generate correctly with level-appropriate vocabulary
|
||||||
|
- Story audio is clear and accessible
|
||||||
|
- Stories unlock sequentially as users complete lessons
|
||||||
|
- Points and badges are awarded correctly
|
||||||
|
- Streaks track daily activity accurately
|
||||||
|
|
||||||
|
### Week 5
|
||||||
|
| Day | Developer | Tasks | Hours | Feature |
|
||||||
|
|-----|-----------|-------|-------|---------|
|
||||||
|
| 21 | Backend | Create StorySegment entity | 2 | 3.1 |
|
||||||
|
| 21 | Backend | Create StoryService | 3 | 3.1 |
|
||||||
|
| 22 | Backend | Create StoryGenerationService | 3 | 3.1 |
|
||||||
|
| 22 | Backend | Implement Mistral integration | 2 | 3.1 |
|
||||||
|
| 23 | Backend | Create StoryController | 2 | 3.1 |
|
||||||
|
| 23 | Backend | Generate audio for stories | 3 | 3.1 |
|
||||||
|
| 24 | Backend | Test Story Integration | 2 | 3.1 |
|
||||||
|
| 24 | Backend | Start Gamification | 2 | 3.2 |
|
||||||
|
|
||||||
|
### Week 6
|
||||||
|
| Day | Developer | Tasks | Hours | Feature |
|
||||||
|
|-----|-----------|-------|-------|---------|
|
||||||
|
| 25 | Backend | Update User entity with gamification fields | 2 | 3.2 |
|
||||||
|
| 25 | Backend | Create Badge/UserBadge entities | 2 | 3.2 |
|
||||||
|
| 26 | Backend | Create PointsService | 2 | 3.2 |
|
||||||
|
| 26 | Backend | Create BadgeService | 3 | 3.2 |
|
||||||
|
| 27 | Backend | Create StreakService | 2 | 3.2 |
|
||||||
|
| 27 | Backend | Create GamificationController | 2 | 3.2 |
|
||||||
|
| 28 | Backend | Write tests for Gamification | 2 | 3.2 |
|
||||||
|
| 28 | Backend | Finalize Phase 3 | 2 | Both |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: Frontend 🎨
|
||||||
|
**Duration:** 2 weeks | **Total Hours:** 10-16h | **Priority:** High
|
||||||
|
|
||||||
|
### Objective
|
||||||
|
Implement the complete React + TypeScript frontend application with all UI components, pages, and services.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
| # | Feature | Description | Hours | Status | Dependencies |
|
||||||
|
|---|---------|-------------|-------|--------|--------------|
|
||||||
|
| 4.1 | [Frontend UI](features/frontend-ui.md) | Complete React frontend | 10-16h | ⏳ Planned | Phase 2-3 |
|
||||||
|
|
||||||
|
### Deliverables
|
||||||
|
- ✅ React 19 + TypeScript + Vite project setup
|
||||||
|
- ✅ Tailwind CSS styling
|
||||||
|
- ✅ All shared components (Button, Input, Card, AudioPlayer, Recorder, Modal, Notification)
|
||||||
|
- ✅ Authentication pages (Login, Register, Profile)
|
||||||
|
- ✅ Dashboard page with progress tracking
|
||||||
|
- ✅ Lesson pages with all tabs (Vocabulary, Grammar, Story, Reading, Listening, Speaking, Writing, Quiz)
|
||||||
|
- ✅ Quiz pages with all question types
|
||||||
|
- ✅ Story pages with audio playback
|
||||||
|
- ✅ Practice pages for speaking/writing
|
||||||
|
- ✅ API client with Axios
|
||||||
|
- ✅ Authentication context and protected routes
|
||||||
|
- ✅ State management with Zustand
|
||||||
|
- ✅ Responsive design for mobile, tablet, desktop
|
||||||
|
- ✅ Accessibility compliance (WCAG 2.1 AA)
|
||||||
|
|
||||||
|
### Success Criteria
|
||||||
|
- All pages load without errors
|
||||||
|
- All components render correctly
|
||||||
|
- Authentication flow works end-to-end
|
||||||
|
- Audio playback and recording work on all supported browsers
|
||||||
|
- Responsive design works on all screen sizes
|
||||||
|
- Application is accessible to screen readers and keyboard users
|
||||||
|
|
||||||
|
### Week 7
|
||||||
|
| Day | Developer | Tasks | Hours | Feature |
|
||||||
|
|-----|-----------|-------|-------|---------|
|
||||||
|
| 29 | Frontend | Initialize Vite + React + TypeScript project | 3 | 4.1 |
|
||||||
|
| 29 | Frontend | Install dependencies (Router, Tailwind, Axios, Zustand) | 2 | 4.1 |
|
||||||
|
| 30 | Frontend | Create API client with interceptors | 2 | 4.1 |
|
||||||
|
| 30 | Frontend | Create AuthContext and protected routes | 3 | 4.1 |
|
||||||
|
| 31 | Frontend | Create Layout components (Header, Footer) | 3 | 4.1 |
|
||||||
|
| 31 | Frontend | Create shared UI components | 3 | 4.1 |
|
||||||
|
| 32 | Frontend | Create Auth pages (Login, Register, Profile) | 4 | 4.1 |
|
||||||
|
|
||||||
|
### Week 8
|
||||||
|
| Day | Developer | Tasks | Hours | Feature |
|
||||||
|
|-----|-----------|-------|-------|---------|
|
||||||
|
| 33 | Frontend | Create Dashboard page | 3 | 4.1 |
|
||||||
|
| 33 | Frontend | Create Lesson page with tabs | 4 | 4.1 |
|
||||||
|
| 34 | Frontend | Create Quiz pages and components | 4 | 4.1 |
|
||||||
|
| 34 | Frontend | Create Story pages and components | 3 | 4.1 |
|
||||||
|
| 35 | Frontend | Create Practice pages | 3 | 4.1 |
|
||||||
|
| 35 | Frontend | Add loading states and error handling | 2 | 4.1 |
|
||||||
|
| 36 | Frontend | Responsive design tweaks | 3 | 4.1 |
|
||||||
|
| 37 | Frontend | Accessibility audit | 2 | 4.1 |
|
||||||
|
| 38 | Frontend | Performance optimization | 2 | 4.1 |
|
||||||
|
| 38 | Frontend | Final testing and polish | 2 | 4.1 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📅 Project Timeline Summary
|
||||||
|
|
||||||
|
| Phase | Duration | Hours | Features | Status |
|
||||||
|
|-------|----------|-------|----------|--------|
|
||||||
|
| Phase 1: Foundation | 2 weeks | 30-42h | 2 | ⏳ Planned |
|
||||||
|
| Phase 2: Core Backend | 2 weeks | 42-58h | 4 | ⏳ Planned |
|
||||||
|
| Phase 3: Content & Features | 2 weeks | 30-42h | 2 | ⏳ Planned |
|
||||||
|
| Phase 4: Frontend | 2 weeks | 10-16h | 1 | ⏳ Planned |
|
||||||
|
| **Total** | **8 weeks** | **112-158h** | **9** | ⏳ Planned |
|
||||||
|
|
||||||
|
**For a small team (2-3 developers):** ~4-5 weeks
|
||||||
|
**For a solo developer:** ~8-10 weeks
|
||||||
|
**For a larger team (4+ developers):** ~3-4 weeks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Resource Allocation Scenarios
|
||||||
|
|
||||||
|
### Scenario 1: Solo Developer (8-10 weeks)
|
||||||
|
|
||||||
|
```
|
||||||
|
Week 1-2: Phase 1 - Foundation (30-42h)
|
||||||
|
Week 3-4: Phase 2 - Core Backend (42-58h)
|
||||||
|
Week 5-6: Phase 3 - Content & Features (30-42h)
|
||||||
|
Week 7-8: Phase 4 - Frontend (10-16h)
|
||||||
|
Week 9-10: Testing, Polish, Bug Fixes (20h)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Total:** ~152-178 hours across 10 weeks
|
||||||
|
|
||||||
|
### Scenario 2: Team of 2 (4-5 weeks)
|
||||||
|
|
||||||
|
**Developer A (Backend Focus):**
|
||||||
|
- Week 1: Infrastructure (14h) + Auth (4h) = 18h
|
||||||
|
- Week 2: Lesson Mgmt (14h) + AI Services (8h) = 22h
|
||||||
|
- Week 3: Vocabulary (10h) + Quiz (8h) = 18h
|
||||||
|
- Week 4: Story (10h) + Gamification (6h) = 16h
|
||||||
|
- Week 5: Frontend support + Testing = 16h
|
||||||
|
|
||||||
|
**Developer B (Full-Stack):**
|
||||||
|
- Week 1: Auth (2h) + Lesson Mgmt (2h) = 4h
|
||||||
|
- Week 2: AI Services (8h) + Vocabulary (2h) = 10h
|
||||||
|
- Week 3: Quiz (2h) + Story (2h) + Gamification (2h) = 6h
|
||||||
|
- Week 4: Frontend (16h) = 16h
|
||||||
|
- Week 5: Frontend (16h) + Testing = 16h
|
||||||
|
|
||||||
|
**Total:** ~142-158 hours across 5 weeks
|
||||||
|
|
||||||
|
### Scenario 3: Team of 3 (3-4 weeks)
|
||||||
|
|
||||||
|
**Developer A (Backend Lead):**
|
||||||
|
- Infrastructure, Auth, Lesson Mgmt, AI Services
|
||||||
|
|
||||||
|
**Developer B (Backend):**
|
||||||
|
- Vocabulary, Quiz, Story, Gamification
|
||||||
|
|
||||||
|
**Developer C (Frontend):**
|
||||||
|
- Wait for Phase 2, then build entire frontend
|
||||||
|
|
||||||
|
**Total:** ~112-158 hours across 3-4 weeks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Milestones & Checkpoints
|
||||||
|
|
||||||
|
### Milestone 1: Foundation Complete (End of Week 2)
|
||||||
|
**Success Metrics:**
|
||||||
|
- [ ] Backend project builds and runs
|
||||||
|
- [ ] Database is configured and accessible
|
||||||
|
- [ ] Docker containers work
|
||||||
|
- [ ] CI/CD pipeline passes
|
||||||
|
- [ ] Authentication works end-to-end
|
||||||
|
- [ ] Can start any Phase 2 feature
|
||||||
|
|
||||||
|
**Exit Criteria:**
|
||||||
|
- All Phase 1 acceptance criteria met
|
||||||
|
- All Phase 1 tests passing
|
||||||
|
- All Phase 1 documentation complete
|
||||||
|
|
||||||
|
### Milestone 2: Core Backend Complete (End of Week 4)
|
||||||
|
**Success Metrics:**
|
||||||
|
- [ ] Lesson management works
|
||||||
|
- [ ] AI services integrate successfully
|
||||||
|
- [ ] Vocabulary system works with audio
|
||||||
|
- [ ] Quiz system works with all question types
|
||||||
|
- [ ] Progress tracking updates correctly
|
||||||
|
- [ ] Can start any Phase 3 feature
|
||||||
|
|
||||||
|
**Exit Criteria:**
|
||||||
|
- All Phase 2 acceptance criteria met
|
||||||
|
- All Phase 2 tests passing
|
||||||
|
- All Phase 2 documentation complete
|
||||||
|
|
||||||
|
### Milestone 3: Content & Features Complete (End of Week 6)
|
||||||
|
**Success Metrics:**
|
||||||
|
- [ ] Story generation and audio works
|
||||||
|
- [ ] Stories unlock sequentially
|
||||||
|
- [ ] Gamification (points, badges, streaks) works
|
||||||
|
- [ ] Can start Frontend implementation
|
||||||
|
|
||||||
|
**Exit Criteria:**
|
||||||
|
- All Phase 3 acceptance criteria met
|
||||||
|
- All Phase 3 tests passing
|
||||||
|
- All Phase 3 documentation complete
|
||||||
|
|
||||||
|
### Milestone 4: Frontend Complete (End of Week 8)
|
||||||
|
**Success Metrics:**
|
||||||
|
- [ ] All pages render without errors
|
||||||
|
- [ ] All components work correctly
|
||||||
|
- [ ] Authentication flow works
|
||||||
|
- [ ] Audio playback and recording works
|
||||||
|
- [ ] Responsive design works
|
||||||
|
- [ ] Application is production-ready
|
||||||
|
|
||||||
|
**Exit Criteria:**
|
||||||
|
- All Phase 4 acceptance criteria met
|
||||||
|
- All Phase 4 tests passing
|
||||||
|
- All Phase 4 documentation complete
|
||||||
|
|
||||||
|
### Milestone 5: Production Deployment (End of Week 9-10)
|
||||||
|
**Success Metrics:**
|
||||||
|
- [ ] All features deployed to production
|
||||||
|
- [ ] Performance meets targets
|
||||||
|
- [ ] Security review complete
|
||||||
|
- [ ] User testing successful
|
||||||
|
- [ ] Bug count is acceptable
|
||||||
|
|
||||||
|
**Exit Criteria:**
|
||||||
|
- Application is live and accessible
|
||||||
|
- Users can register, login, and use all features
|
||||||
|
- No critical bugs
|
||||||
|
- Performance is acceptable
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚨 Critical Path Analysis
|
||||||
|
|
||||||
|
The **critical path** (longest sequence of dependent tasks) is:
|
||||||
|
|
||||||
|
```
|
||||||
|
Infrastructure Setup (10-14h)
|
||||||
|
↓
|
||||||
|
User Authentication (4-6h)
|
||||||
|
↓
|
||||||
|
Lesson Management (10-16h)
|
||||||
|
↓
|
||||||
|
Vocabulary System (8-12h) + Quiz System (6-10h) [Parallel]
|
||||||
|
↓
|
||||||
|
Story Integration (8-12h) + Gamification (6-8h) [Parallel]
|
||||||
|
↓
|
||||||
|
Frontend UI (10-16h)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Total Critical Path: 56-82 hours** (~7-10 days)
|
||||||
|
|
||||||
|
This means the **minimum project duration** is determined by this path, even with parallel development on other features.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 Risk Management
|
||||||
|
|
||||||
|
### Top 5 Project Risks
|
||||||
|
|
||||||
|
| # | Risk | Likelihood | Impact | Mitigation | Owner | Phase |
|
||||||
|
|---|------|------------|--------|------------|-------|-------|
|
||||||
|
| 1 | Python-.NET integration failures | High | High | Use Process.Start initially, implement proper error handling | Backend | 2 |
|
||||||
|
| 2 | AI service performance issues | High | Medium | Implement async processing, rate limiting, caching | Backend | 2 |
|
||||||
|
| 3 | Vosk/Coqui model compatibility | Medium | High | Test with models before implementation, have fallbacks | Backend | 2 |
|
||||||
|
| 4 | Mistral API costs exceed budget | Medium | High | Monitor usage, cache aggressively, set budget alerts | Product | 2 |
|
||||||
|
| 5 | Scope creep (adding more features) | Medium | Medium | Stick to MVP scope, defer nice-to-haves | PM | All |
|
||||||
|
|
||||||
|
### Risk Monitoring
|
||||||
|
|
||||||
|
**Daily:** Check AI service health and costs
|
||||||
|
**Weekly:** Review progress against roadmap
|
||||||
|
**Phase End:** Conduct risk review before starting next phase
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Tooling & Environment
|
||||||
|
|
||||||
|
### Development Environment
|
||||||
|
- **OS:** Linux (recommended), Windows 10/11, or macOS
|
||||||
|
- **Backend:** .NET 9.0 SDK
|
||||||
|
- **Frontend:** Node.js 18+, npm/yarn
|
||||||
|
- **Database:** PostgreSQL 15+
|
||||||
|
- **AI Services:**
|
||||||
|
- Python 3.8+
|
||||||
|
- Vosk + vosk-model-de-0.22 (~500MB)
|
||||||
|
- Coqui TTS + German model (~1.5GB)
|
||||||
|
- **Docker:** Docker Desktop or Docker Engine
|
||||||
|
- **IDE:** Visual Studio Code, Rider, or Visual Studio
|
||||||
|
|
||||||
|
### DevOps
|
||||||
|
- **Version Control:** Git + GitHub
|
||||||
|
- **CI/CD:** GitHub Actions
|
||||||
|
- **Containerization:** Docker + Docker Compose
|
||||||
|
- **Monitoring:** Health checks, logging
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎓 Team Onboarding
|
||||||
|
|
||||||
|
### New Team Member Checklist
|
||||||
|
|
||||||
|
1. **Environment Setup** (Day 1)
|
||||||
|
- [ ] Clone repository
|
||||||
|
- [ ] Install .NET 9.0 SDK
|
||||||
|
- [ ] Install Node.js 18+
|
||||||
|
- [ ] Install PostgreSQL
|
||||||
|
- [ ] Install Docker
|
||||||
|
- [ ] Install Python 3.8+
|
||||||
|
- [ ] Download Vosk model
|
||||||
|
- [ ] Download Coqui TTS model
|
||||||
|
- [ ] Run `docker-compose up`
|
||||||
|
- [ ] Verify all services are running
|
||||||
|
|
||||||
|
2. **Project Familiarization** (Day 2)
|
||||||
|
- [ ] Read AGENTS.md
|
||||||
|
- [ ] Read Application Plan
|
||||||
|
- [ ] Review Clean Architecture structure
|
||||||
|
- [ ] Review current feature plans
|
||||||
|
- [ ] Understand development workflow
|
||||||
|
|
||||||
|
3. **First Task** (Day 3)
|
||||||
|
- [ ] Pick a "good first issue" from backlog
|
||||||
|
- [ ] Create feature branch
|
||||||
|
- [ ] Implement with tests
|
||||||
|
- [ ] Submit PR for review
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Success Metrics
|
||||||
|
|
||||||
|
### Quality Metrics
|
||||||
|
| Metric | Target | Measurement |
|
||||||
|
|--------|--------|-------------|
|
||||||
|
| Code Coverage | 80%+ | SonarQube / Coverlet |
|
||||||
|
| Test Pass Rate | 100% | CI/CD Pipeline |
|
||||||
|
| Build Success Rate | 99% | CI/CD Pipeline |
|
||||||
|
| Deployment Frequency | Daily | GitHub Actions |
|
||||||
|
| Mean Time to Repair | <4h | Incident Tracking |
|
||||||
|
|
||||||
|
### Performance Metrics
|
||||||
|
| Metric | Target | Measurement |
|
||||||
|
|--------|--------|-------------|
|
||||||
|
| Backend Response Time | <500ms | Health Checks |
|
||||||
|
| Frontend Load Time | <2s | Lighthouse |
|
||||||
|
| API Latency (p95) | <300ms | Application Insights |
|
||||||
|
| AI Service Response | <5s | Custom Monitoring |
|
||||||
|
|
||||||
|
### Business Metrics
|
||||||
|
| Metric | Target | Measurement |
|
||||||
|
|--------|--------|-------------|
|
||||||
|
| User Registration | 100+/month | Analytics |
|
||||||
|
| Active Users | 50+/day | Analytics |
|
||||||
|
| Lesson Completion Rate | 80%+ | Database |
|
||||||
|
| Quiz Pass Rate | 80%+ | Database |
|
||||||
|
| User Retention (7-day) | 50%+ | Analytics |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Version History
|
||||||
|
|
||||||
|
| Version | Date | Author | Changes |
|
||||||
|
|---------|------|--------|---------|
|
||||||
|
| 1.0 | May 31, 2025 | Vibe AI | Initial roadmap based on feature plans |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Related Documentation
|
||||||
|
|
||||||
|
- [Feature Plans](features/README.md) - Detailed feature implementation plans
|
||||||
|
- [AGENTS.md](../AGENTS.md) - Development rules and workflows
|
||||||
|
- [Application Plan](architecture/application-plan.md) - Overall project vision
|
||||||
|
- [Backend Structure](architecture/backend-structure.md) - Technical architecture
|
||||||
|
- [Frontend Structure](architecture/frontend-structure.md) - Frontend architecture
|
||||||
|
- [Database Schema](database/initial-database-schema.sql) - Database design
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: May 31, 2025*
|
||||||
|
*Roadmap based on Clean Architecture, TDD, and Agile principles*
|
||||||
1541
docs/architecture/application-plan.md
Normal file
1541
docs/architecture/application-plan.md
Normal file
File diff suppressed because it is too large
Load diff
61
docs/architecture/backend-structure.md
Normal file
61
docs/architecture/backend-structure.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
GermanApp/
|
||||||
|
├── Controllers/
|
||||||
|
│ ├── AuthController.cs -- User registration/login
|
||||||
|
│ ├── LessonsController.cs -- Lesson CRUD and retrieval
|
||||||
|
│ ├── QuizzesController.cs -- Quiz retrieval and submission
|
||||||
|
│ ├── StoryController.cs -- Story segment retrieval
|
||||||
|
│ ├── SpeechController.cs -- Vosk speech recognition
|
||||||
|
│ ├── TtsController.cs -- Coqui TTS audio generation
|
||||||
|
│ ├── VocabularyController.cs -- Vocabulary retrieval
|
||||||
|
│ └── UserProgressController.cs -- User progress tracking
|
||||||
|
│
|
||||||
|
├── Services/
|
||||||
|
│ ├── AuthService.cs
|
||||||
|
│ ├── LessonService.cs
|
||||||
|
│ ├── QuizService.cs
|
||||||
|
│ ├── StoryService.cs
|
||||||
|
│ ├── VoskService.cs -- Vosk integration
|
||||||
|
│ ├── TtsService.cs -- Coqui TTS integration
|
||||||
|
│ ├── MistralService.cs -- Mistral-Medium API calls
|
||||||
|
│ ├── VocabularyService.cs
|
||||||
|
│ └── UserProgressService.cs
|
||||||
|
│
|
||||||
|
├── Models/
|
||||||
|
│ ├── DTOs/ -- Data Transfer Objects
|
||||||
|
│ │ ├── LessonDto.cs
|
||||||
|
│ │ ├── QuizDto.cs
|
||||||
|
│ │ ├── StorySegmentDto.cs
|
||||||
|
│ │ ├── VocabularyDto.cs
|
||||||
|
│ │ └── UserProgressDto.cs
|
||||||
|
│ │
|
||||||
|
│ ├── Entities/ -- Database entities (mirroring schema)
|
||||||
|
│ │ ├── User.cs
|
||||||
|
│ │ ├── Lesson.cs
|
||||||
|
│ │ ├── Vocabulary.cs
|
||||||
|
│ │ ├── WordMetadata.cs
|
||||||
|
│ │ ├── WordForm.cs
|
||||||
|
│ │ ├── StorySegment.cs
|
||||||
|
│ │ ├── Quiz.cs
|
||||||
|
│ │ ├── Question.cs
|
||||||
|
│ │ ├── QuestionOption.cs
|
||||||
|
│ │ ├── UserProgress.cs
|
||||||
|
│ │ ├── QuizAttempt.cs
|
||||||
|
│ │ └── ...
|
||||||
|
│ │
|
||||||
|
│ └── Requests/ -- API request models
|
||||||
|
│ ├── SubmitQuizRequest.cs
|
||||||
|
│ ├── GenerateTtsRequest.cs
|
||||||
|
│ └── ...
|
||||||
|
│
|
||||||
|
├── Data/
|
||||||
|
│ ├── AppDbContext.cs -- Entity Framework Core context
|
||||||
|
│ ├── Migrations/ -- EF Core migrations
|
||||||
|
│ └── SeedData.cs -- Initial data seeding
|
||||||
|
│
|
||||||
|
├── Utilities/
|
||||||
|
│ ├── AudioHelper.cs -- Audio file handling
|
||||||
|
│ ├── ValidationHelper.cs -- Input validation
|
||||||
|
│ └── ...
|
||||||
|
│
|
||||||
|
├── appsettings.json -- Configuration (DB, Vosk, Coqui, Mistral)
|
||||||
|
└── Program.cs -- Startup and middleware
|
||||||
119
docs/architecture/frontend-structure.md
Normal file
119
docs/architecture/frontend-structure.md
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
german-app-frontend/
|
||||||
|
│
|
||||||
|
├── public/ # Static files
|
||||||
|
│ ├── audio/ # Generated audio files (served statically)
|
||||||
|
│ │ ├── vocabulary/ # Vocabulary word audio (e.g., 1.wav, 2.wav)
|
||||||
|
│ │ ├── story/ # Story segment audio
|
||||||
|
│ │ └── quiz/ # Quiz question audio
|
||||||
|
│ │
|
||||||
|
│ ├── favicon.ico
|
||||||
|
│ └── index.html # Single HTML entry point
|
||||||
|
│
|
||||||
|
├── src/ # Source code
|
||||||
|
│ │
|
||||||
|
│ ├── assets/ # Static assets (images, fonts, etc.)
|
||||||
|
│ │ ├── images/
|
||||||
|
│ │ │ ├── badges/ # Badge icons
|
||||||
|
│ │ │ ├── flags/ # Language flags
|
||||||
|
│ │ │ └── ...
|
||||||
|
│ │ └── fonts/
|
||||||
|
│ │
|
||||||
|
│ ├── components/ # Reusable UI components
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── common/ # Generic, reusable components
|
||||||
|
│ │ │ ├── AudioPlayer.tsx # Plays audio files (vocabulary, story, quiz)
|
||||||
|
│ │ │ ├── Recorder.tsx # Records user speech for speaking exercises
|
||||||
|
│ │ │ ├── Button.tsx # Reusable button with variants
|
||||||
|
│ │ │ ├── Modal.tsx # Modal dialog
|
||||||
|
│ │ │ ├── Spinner.tsx # Loading spinner
|
||||||
|
│ │ │ ├── Card.tsx # Reusable card component
|
||||||
|
│ │ │ └── index.ts # Exports all common components
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── layout/ # Layout-related components
|
||||||
|
│ │ │ ├── Header.tsx # Top navigation bar
|
||||||
|
│ │ │ ├── Footer.tsx # Footer component
|
||||||
|
│ │ │ ├── Sidebar.tsx # Sidebar for navigation (if needed)
|
||||||
|
│ │ │ └── Layout.tsx # Main layout wrapper
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── lesson/ # Lesson-specific components
|
||||||
|
│ │ │ ├── VocabularyTab.tsx # Displays vocabulary words with audio
|
||||||
|
│ │ │ ├── GrammarTab.tsx # Displays grammar explanations
|
||||||
|
│ │ │ ├── StoryTab.tsx # Displays story segments with audio
|
||||||
|
│ │ │ ├── PracticeTab.tsx # Speaking/writing/listening exercises
|
||||||
|
│ │ │ └── index.ts # Exports lesson components
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── quiz/ # Quiz-specific components
|
||||||
|
│ │ │ ├── McqQuestion.tsx # Multiple-choice question
|
||||||
|
│ │ │ ├── FillInBlank.tsx # Fill-in-the-blank question
|
||||||
|
│ │ │ ├── ListeningQuestion.tsx # Listening comprehension question
|
||||||
|
│ │ │ ├── MatchingQuestion.tsx # Matching question (e.g., word to article)
|
||||||
|
│ │ │ ├── QuizResults.tsx # Displays quiz results
|
||||||
|
│ │ │ └── index.ts # Exports quiz components
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── story/ # Story-specific components
|
||||||
|
│ │ │ ├── StorySegment.tsx # Displays a single story segment
|
||||||
|
│ │ │ └── StoryPlayer.tsx # Handles story audio playback
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── dashboard/ # Dashboard-specific components
|
||||||
|
│ │ │ ├── ProgressBar.tsx # Shows progress for a level
|
||||||
|
│ │ │ ├── LessonCard.tsx # Card for a lesson (title, status, etc.)
|
||||||
|
│ │ │ ├── StoryProgress.tsx # Shows story unlock progress
|
||||||
|
│ │ │ ├── BadgeDisplay.tsx # Displays earned badges
|
||||||
|
│ │ │ └── index.ts
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── practice/ # Practice-specific components
|
||||||
|
│ │ │ ├── SpeakingExercise.tsx # Speaking practice with recorder
|
||||||
|
│ │ │ ├── WritingExercise.tsx # Writing practice with Mistral feedback
|
||||||
|
│ │ │ └── ListeningExercise.tsx # Listening practice
|
||||||
|
│ │ │
|
||||||
|
│ │ └── shared/ # Shared logic/components
|
||||||
|
│ │ ├── ProtectedRoute.tsx # Wraps routes that require auth
|
||||||
|
│ │ ├── PrivateRoute.tsx # Alternative name for ProtectedRoute
|
||||||
|
│ │ └── ErrorBoundary.tsx # Catches and displays errors
|
||||||
|
│ │
|
||||||
|
│ ├── context/ # React Context providers
|
||||||
|
│ │ ├── AuthContext.tsx # Manages authentication state
|
||||||
|
│ │ ├── UserProgressContext.tsx # Manages user progress (optional)
|
||||||
|
│ │ └── index.ts # Exports all contexts
|
||||||
|
│ │
|
||||||
|
│ ├── hooks/ # Custom React hooks
|
||||||
|
│ │ ├── useAuth.ts # Manages auth state (login, logout, etc.)
|
||||||
|
│ │ ├── useAudio.ts # Handles audio playback logic
|
||||||
|
│ │ ├── useRecorder.ts # Handles audio recording logic
|
||||||
|
│ │ ├── useApi.ts # Axios API client with interceptors
|
||||||
|
│ │ ├── useLessons.ts # Fetches and manages lesson data
|
||||||
|
│ │ ├── useQuizzes.ts # Fetches and manages quiz data
|
||||||
|
│ │ ├── useUserProgress.ts # Fetches and manages user progress
|
||||||
|
│ │ ├── useStory.ts # Fetches and manages story segments
|
||||||
|
│ │ └── index.ts # Exports all hooks
|
||||||
|
│ │
|
||||||
|
│ ├── pages/ # Page-level components (routes)
|
||||||
|
│ │ ├── DashboardPage.tsx # User dashboard (progress, next lesson, etc.)
|
||||||
|
│ │ ├── LessonPage.tsx # Lesson page (tabs for vocabulary, grammar, story, quiz)
|
||||||
|
│ │ ├── QuizPage.tsx # Standalone quiz page (if needed)
|
||||||
|
│ │ ├── StoryPage.tsx # Full story viewer (all unlocked segments)
|
||||||
|
│ │ ├── PracticePage.tsx # Practice exercises (speaking, writing, listening)
|
||||||
|
│ │ ├── ProfilePage.tsx # User profile (badges, settings, etc.)
|
||||||
|
│ │ ├── LoginPage.tsx # Login form
|
||||||
|
│ │ ├── RegisterPage.tsx # Registration form
|
||||||
|
│ │ ├── NotFoundPage.tsx # 404 page
|
||||||
|
│ │ └── index.ts # Exports all pages
|
||||||
|
│ │
|
||||||
|
│ ├── services/ # API service layer
|
||||||
|
│ │ ├── api.ts # Axios instance with interceptors
|
||||||
|
│ │ ├── authService.ts # Authentication API calls
|
||||||
|
│ │ ├── lessonService.ts # Lesson-related API calls
|
||||||
|
│ │ ├── quizService.ts # Quiz-related API calls
|
||||||
|
│ │ ├── storyService.ts # Story-related API calls
|
||||||
|
│ │ ├── speechService.ts # Speech recognition API calls
|
||||||
|
│ │ ├── ttsService.ts # TTS API calls
|
||||||
|
│ │ ├── userProgressService.ts # User progress API calls
|
||||||
|
│ │ └── index.ts # Exports all services
|
||||||
|
│ │
|
||||||
|
│ ├── store/ # State management (optional, if using Zustand/Redux)
|
||||||
|
│ │ ├── slices/ # Redux slices (if using Redux)
|
||||||
|
│ │ │ ├── authSlice.ts
|
||||||
|
│ │ │ ├── userSlice.ts
|
||||||
|
│ │ │ └── ...
|
||||||
|
│ │ ├── store.ts # Redux store configuration
|
||||||
|
│ │ └── hooks.ts # Redux hooks
|
||||||
242
docs/database/initial-database-schema.sql
Normal file
242
docs/database/initial-database-schema.sql
Normal file
|
|
@ -0,0 +1,242 @@
|
||||||
|
-- Enable UUID extension (optional, but useful for unique IDs)
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **1. Users and Authentication**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Users table
|
||||||
|
CREATE TABLE Users (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
Username VARCHAR(50) UNIQUE NOT NULL,
|
||||||
|
Email VARCHAR(100) UNIQUE NOT NULL,
|
||||||
|
PasswordHash VARCHAR(255) NOT NULL,
|
||||||
|
Role VARCHAR(20) DEFAULT 'user' CHECK (Role IN ('user', 'admin')),
|
||||||
|
LastLoginAt TIMESTAMP,
|
||||||
|
CreatedAt TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **2. Learning Content: Levels, Lessons, and Dependencies**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Levels table
|
||||||
|
CREATE TABLE Levels (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
Name VARCHAR(10) UNIQUE NOT NULL, -- e.g., "A1", "A2"
|
||||||
|
Description TEXT,
|
||||||
|
Order INT UNIQUE NOT NULL,
|
||||||
|
IsActive BOOLEAN DEFAULT TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Lessons table
|
||||||
|
CREATE TABLE Lessons (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LevelId INT REFERENCES Levels(Id) ON DELETE CASCADE,
|
||||||
|
Title VARCHAR(100) NOT NULL,
|
||||||
|
Description TEXT,
|
||||||
|
Order INT NOT NULL,
|
||||||
|
EstimatedMinutes INT,
|
||||||
|
UNIQUE(LevelId, Order)
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **3. Vocabulary and Word Details**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Vocabulary table (core words)
|
||||||
|
CREATE TABLE Vocabulary (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE,
|
||||||
|
BaseWord VARCHAR(50) NOT NULL, -- e.g., "gehen", "Buch"
|
||||||
|
UNIQUE(LessonId, BaseWord)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- WordMetadata table (metadata for vocabulary, e.g., frequency, part of speech)
|
||||||
|
CREATE TABLE WordMetadata (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
VocabularyId INT REFERENCES Vocabulary(Id) ON DELETE CASCADE,
|
||||||
|
Translation VARCHAR(100) NOT NULL,
|
||||||
|
WordClass VARCHAR(20) NOT NULL CHECK (WordClass IN ('noun', 'verb', 'adjective', 'adverb', 'preposition', 'conjunction', 'pronoun', 'article', 'other')),
|
||||||
|
Frequency INT CHECK (Frequency BETWEEN 1 AND 5), -- 1 = rare, 5 = very common
|
||||||
|
AudioUrl VARCHAR(255) NOT NULL,
|
||||||
|
ImageUrl VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- WordForms table (inflections, plurals, conjugations, etc.)
|
||||||
|
CREATE TABLE WordForms (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
VocabularyId INT REFERENCES Vocabulary(Id) ON DELETE CASCADE,
|
||||||
|
FormType VARCHAR(20) NOT NULL CHECK (FormType IN ('plural', 'singular', 'infinitive', 'past_tense', 'past_participle', 'present_participle', 'conjugation_ich', 'conjugation_du', 'conjugation_er', 'conjugation_wir', 'conjugation_ihr', 'conjugation_sie', 'dative', 'accusative', 'genitive', 'nominative')),
|
||||||
|
Form VARCHAR(50) NOT NULL,
|
||||||
|
Article VARCHAR(10) CHECK (Article IN ('der', 'die', 'das', '')), -- Only for nouns
|
||||||
|
AudioUrl VARCHAR(255),
|
||||||
|
UNIQUE(VocabularyId, FormType, Form)
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **4. Story Segments**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- StorySegments table
|
||||||
|
CREATE TABLE StorySegments (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LevelId INT REFERENCES Levels(Id) ON DELETE CASCADE,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE NOT NULL, -- Required
|
||||||
|
Title VARCHAR(100) NOT NULL,
|
||||||
|
Content TEXT NOT NULL,
|
||||||
|
AudioUrl VARCHAR(255) NOT NULL,
|
||||||
|
Order INT NOT NULL,
|
||||||
|
IsUnlocked BOOLEAN DEFAULT FALSE, -- Managed by the app logic (unlocked via lesson completion)
|
||||||
|
UNIQUE(LevelId, Order)
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **5. Quizzes and Questions**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Quizzes table
|
||||||
|
CREATE TABLE Quizzes (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE,
|
||||||
|
Title VARCHAR(100) NOT NULL,
|
||||||
|
Description TEXT,
|
||||||
|
PassingScore INT DEFAULT 80
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Questions table
|
||||||
|
CREATE TABLE Questions (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
QuizId INT REFERENCES Quizzes(Id) ON DELETE CASCADE,
|
||||||
|
Type VARCHAR(20) NOT NULL CHECK (Type IN ('mcq', 'fill_in', 'listening', 'matching')),
|
||||||
|
Content TEXT NOT NULL,
|
||||||
|
CorrectAnswer TEXT NOT NULL,
|
||||||
|
AudioUrl VARCHAR(255),
|
||||||
|
AudioScript TEXT, -- For listening questions: the text of the audio
|
||||||
|
Explanation TEXT,
|
||||||
|
Points INT DEFAULT 1,
|
||||||
|
Difficulty INT CHECK (Difficulty BETWEEN 1 AND 5)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- QuestionOptions table (normalized for MCQ)
|
||||||
|
CREATE TABLE QuestionOptions (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
QuestionId INT REFERENCES Questions(Id) ON DELETE CASCADE,
|
||||||
|
OptionText TEXT NOT NULL,
|
||||||
|
Order INT NOT NULL,
|
||||||
|
UNIQUE(QuestionId, Order)
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **6. User Progress and Quiz Attempts**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- UserProgress table
|
||||||
|
CREATE TABLE UserProgress (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE,
|
||||||
|
IsCompleted BOOLEAN DEFAULT FALSE,
|
||||||
|
CurrentLevelId INT REFERENCES Levels(Id), -- Moved from Users
|
||||||
|
Streak INT DEFAULT 0,
|
||||||
|
TotalPoints INT DEFAULT 0,
|
||||||
|
TimeSpentMinutes INT DEFAULT 0,
|
||||||
|
LastVisitedAt TIMESTAMP DEFAULT NOW(),
|
||||||
|
UNIQUE(UserId, LessonId)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- QuizAttempts table (tracks all attempts)
|
||||||
|
CREATE TABLE QuizAttempts (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
QuizId INT REFERENCES Quizzes(Id) ON DELETE CASCADE,
|
||||||
|
Score INT NOT NULL,
|
||||||
|
TotalPoints INT NOT NULL,
|
||||||
|
Passed BOOLEAN NOT NULL,
|
||||||
|
AttemptDate TIMESTAMP DEFAULT NOW(),
|
||||||
|
TimeSpentSeconds INT
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **7. Gamification**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Badges table
|
||||||
|
CREATE TABLE Badges (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
Name VARCHAR(50) NOT NULL,
|
||||||
|
Description TEXT,
|
||||||
|
ImageUrl VARCHAR(255),
|
||||||
|
PointsRequired INT,
|
||||||
|
Category VARCHAR(50),
|
||||||
|
UNIQUE(Name)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- UserBadges table
|
||||||
|
CREATE TABLE UserBadges (
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
BadgeId INT REFERENCES Badges(Id) ON DELETE CASCADE,
|
||||||
|
EarnedDate TIMESTAMP DEFAULT NOW(),
|
||||||
|
PRIMARY KEY (UserId, BadgeId)
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **8. Practice Sessions**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- PracticeSessions table
|
||||||
|
CREATE TABLE PracticeSessions (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
Type VARCHAR(20) NOT NULL CHECK (Type IN ('speaking', 'writing')),
|
||||||
|
Prompt TEXT NOT NULL,
|
||||||
|
UserResponse TEXT,
|
||||||
|
Feedback TEXT,
|
||||||
|
Score INT,
|
||||||
|
TimeSpentSeconds INT,
|
||||||
|
Date TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **9. User Settings**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- UserSettings table
|
||||||
|
CREATE TABLE UserSettings (
|
||||||
|
UserId INT PRIMARY KEY REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
AudioAutoplay BOOLEAN DEFAULT TRUE,
|
||||||
|
Theme VARCHAR(20) DEFAULT 'light' CHECK (Theme IN ('light', 'dark')),
|
||||||
|
NativeLanguage VARCHAR(50) DEFAULT 'en'
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **10. Feedback**
|
||||||
|
---
|
||||||
|
|
||||||
|
-- Feedback table
|
||||||
|
CREATE TABLE Feedback (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE SET NULL,
|
||||||
|
QuizId INT REFERENCES Quizzes(Id) ON DELETE SET NULL,
|
||||||
|
Rating INT CHECK (Rating BETWEEN 1 AND 5),
|
||||||
|
Comment TEXT,
|
||||||
|
CreatedAt TIMESTAMP DEFAULT NOW(),
|
||||||
|
CHECK (LessonId IS NOT NULL OR QuizId IS NOT NULL)
|
||||||
|
);
|
||||||
|
|
||||||
|
---
|
||||||
|
--- **11. Indexes for Performance**
|
||||||
|
---
|
||||||
|
|
||||||
|
CREATE INDEX idx_userprogress_userid ON UserProgress(UserId);
|
||||||
|
CREATE INDEX idx_userprogress_lessonid ON UserProgress(LessonId);
|
||||||
|
CREATE INDEX idx_vocabulary_lessonid ON Vocabulary(LessonId);
|
||||||
|
CREATE INDEX idx_wordmetadata_vocabularyid ON WordMetadata(VocabularyId);
|
||||||
|
CREATE INDEX idx_wordforms_vocabularyid ON WordForms(VocabularyId);
|
||||||
|
CREATE INDEX idx_questions_quizid ON Questions(QuizId);
|
||||||
|
CREATE INDEX idx_questionoptions_questionid ON QuestionOptions(QuestionId);
|
||||||
|
CREATE INDEX idx_quizattempts_userid ON QuizAttempts(UserId);
|
||||||
|
CREATE INDEX idx_quizattempts_quizid ON QuizAttempts(QuizId);
|
||||||
|
CREATE INDEX idx_storysegments_levelid ON StorySegments(LevelId);
|
||||||
|
CREATE INDEX idx_storysegments_lessonid ON StorySegments(LessonId);
|
||||||
2
docs/development/how-to-run-vibe.md
Normal file
2
docs/development/how-to-run-vibe.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
source ~/.venv/mistral-vibe/bin/activate
|
||||||
|
vibe
|
||||||
373
docs/features/README.md
Normal file
373
docs/features/README.md
Normal file
|
|
@ -0,0 +1,373 @@
|
||||||
|
# Feature Tracking & Implementation Plans
|
||||||
|
|
||||||
|
This directory contains implementation plans and progress tracking for features in the **DeutschLernen** solution. Each feature follows a comprehensive template with **Definition of Done**, **Testing Strategy**, and detailed technical design.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Feature Lifecycle
|
||||||
|
|
||||||
|
Each feature goes through the following stages:
|
||||||
|
|
||||||
|
```
|
||||||
|
Backlog → Planned → In Progress → Code Review → Completed
|
||||||
|
↓ ↓ ↓
|
||||||
|
(Prioritized) (Active Dev) (Testing/QA)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
features/
|
||||||
|
├── README.md # This file - Feature tracking overview & roadmap
|
||||||
|
├── template.md # Template for new feature implementation plans
|
||||||
|
├── ai-services.md # Mistral, Vosk, Coqui TTS integration
|
||||||
|
├── frontend-ui.md # React + TypeScript frontend application
|
||||||
|
├── gamification.md # Points, badges, streaks system
|
||||||
|
├── infrastructure-setup.md # Backend, DB, Docker, CI/CD foundation
|
||||||
|
├── lesson-management.md # Lessons, Levels, Progress tracking
|
||||||
|
├── quiz-system.md # Multiple question types, scoring, results
|
||||||
|
├── story-integration.md # AI-generated stories with audio
|
||||||
|
├── user-authentication.md # JWT-based auth system
|
||||||
|
└── vocabulary-system.md # Words, articles, audio, import
|
||||||
|
```
|
||||||
|
|
||||||
|
Each feature file contains:
|
||||||
|
- 📌 **Overview** - Purpose, user stories, acceptance criteria
|
||||||
|
- 📋 **Requirements** - Functional & non-functional with priorities
|
||||||
|
- 🏗️ **Technical Design** - Architecture, data flow, API endpoints
|
||||||
|
- 🚀 **Implementation Plan** - Phases, milestones, tasks
|
||||||
|
- ✅ **Definition of Done** - General + feature-specific criteria
|
||||||
|
- 🧪 **Testing Strategy** - Test types, tools, feature-specific test cases
|
||||||
|
- 📝 **Notes & Decisions** - Decisions, technical notes, gotchas
|
||||||
|
- 🔗 **Related Files** - Cross-references to architecture docs
|
||||||
|
|
||||||
|
**AI Services** also includes:
|
||||||
|
- 🚨 **Risks & Mitigations** - 18 identified risks with owners
|
||||||
|
- 🔧 **Technical Deep Dive** - Python-.NET integration patterns with code examples
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗺️ Development Roadmap
|
||||||
|
|
||||||
|
Based on dependencies and complexity, here's the recommended implementation order:
|
||||||
|
|
||||||
|
### Phase 1: Foundation (Weeks 1-2)
|
||||||
|
**Total: ~30-42 hours** | **Prerequisite: None**
|
||||||
|
|
||||||
|
| # | Feature | Priority | Estimate | Dependencies | Status |
|
||||||
|
|---|---------|----------|----------|--------------|--------|
|
||||||
|
| 1 | [Infrastructure Setup](infrastructure-setup.md) | High | 10-14h | None | ⏳ Planned |
|
||||||
|
| 2 | [User Authentication](user-authentication.md) | High | 4-6h | Infrastructure | ⏳ Planned |
|
||||||
|
|
||||||
|
**Goal:** Have a working backend project, database, and authentication system.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 2: Core Backend (Weeks 3-4)
|
||||||
|
**Total: ~42-58 hours** | **Prerequisite: Phase 1**
|
||||||
|
|
||||||
|
| # | Feature | Priority | Estimate | Dependencies | Status |
|
||||||
|
|---|---------|----------|----------|--------------|--------|
|
||||||
|
| 3 | [Lesson Management](lesson-management.md) | High | 10-16h | Infrastructure, Auth | ⏳ Planned |
|
||||||
|
| 4 | [AI Services](ai-services.md) | High | 10-16h | Infrastructure | ⏳ Planned |
|
||||||
|
| 5 | [Vocabulary System](vocabulary-system.md) | High | 8-12h | Infrastructure, Lessons | ⏳ Planned |
|
||||||
|
| 6 | [Quiz System](quiz-system.md) | High | 6-10h | Infrastructure, Lessons | ⏳ Planned |
|
||||||
|
|
||||||
|
**Goal:** Have all core backend functionality working with AI integration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3: Content & Features (Weeks 5-6)
|
||||||
|
**Total: ~30-42 hours** | **Prerequisite: Phase 2**
|
||||||
|
|
||||||
|
| # | Feature | Priority | Estimate | Dependencies | Status |
|
||||||
|
|---|---------|----------|----------|--------------|--------|
|
||||||
|
| 7 | [Story Integration](story-integration.md) | High | 8-12h | Lessons, AI Services | ⏳ Planned |
|
||||||
|
| 8 | [Gamification](gamification.md) | Medium | 6-8h | Auth, Lessons, Quiz | ⏳ Planned |
|
||||||
|
|
||||||
|
**Goal:** Have all content management and gamification features working.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4: Frontend (Weeks 7-8)
|
||||||
|
**Total: ~10-16 hours** | **Prerequisite: Phase 2-3**
|
||||||
|
|
||||||
|
| # | Feature | Priority | Estimate | Dependencies | Status |
|
||||||
|
|---|---------|----------|----------|--------------|--------|
|
||||||
|
| 9 | [Frontend UI](frontend-ui.md) | High | 10-16h | All backend features | ⏳ Planned |
|
||||||
|
|
||||||
|
**Goal:** Complete frontend application with all UI components and pages.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Complete Timeline
|
||||||
|
|
||||||
|
```
|
||||||
|
Week 1-2: Phase 1 - Foundation (30-42h)
|
||||||
|
│
|
||||||
|
├── Infrastructure Setup (10-14h)
|
||||||
|
└── User Authentication (4-6h)
|
||||||
|
|
||||||
|
Week 3-4: Phase 2 - Core Backend (42-58h)
|
||||||
|
│
|
||||||
|
├── Lesson Management (10-16h)
|
||||||
|
├── AI Services (10-16h)
|
||||||
|
├── Vocabulary System (8-12h)
|
||||||
|
└── Quiz System (6-10h)
|
||||||
|
|
||||||
|
Week 5-6: Phase 3 - Content & Features (30-42h)
|
||||||
|
│
|
||||||
|
├── Story Integration (8-12h)
|
||||||
|
└── Gamification (6-8h)
|
||||||
|
|
||||||
|
Week 7-8: Phase 4 - Frontend (10-16h)
|
||||||
|
│
|
||||||
|
└── Frontend UI (10-16h)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Total Estimated Time: 112-158 hours (~3-4 weeks for a small team)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Dependency Graph
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ DEPENDENCY GRAPH │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||||
|
│ │Infrastructure │ │User Auth │ │
|
||||||
|
│ │ Setup │ │ │ │
|
||||||
|
│ └────────┬─────────┘ └────────┬─────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
│ └─────────────────────────┴─────────────────┐ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ┌──────────────────┬──────────────────┬───────────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌──────────────────┐ ┌─────────────┐ ┌──────────────┐ │
|
||||||
|
│ │Lesson │ │AI Services │ │Vocabulary │ │
|
||||||
|
│ │Management │ │ │ │System │ │
|
||||||
|
│ └────────┬─────────┘ └──────┬──────┘ └──────┬───────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌─────────────────────────────────────────────┐ │
|
||||||
|
│ │ Quiz System │ │
|
||||||
|
│ └────────────────────────┬────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌──────────────────────────┬──────────────────┐ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌─────────┐ │
|
||||||
|
│ │Story │ │Gamification │ │Frontend │ │
|
||||||
|
│ │Integration │ │ │ │UI │ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └─────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
LEGEND:
|
||||||
|
▼ = Dependency (must be completed first)
|
||||||
|
→ = Data flow
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 Resource Allocation (Sample)
|
||||||
|
|
||||||
|
### Team of 2 Developers (4 weeks)
|
||||||
|
|
||||||
|
| Week | Developer A | Developer B | Total Hours |
|
||||||
|
|------|-------------|-------------|-------------|
|
||||||
|
| 1 | Infrastructure Setup (14h) | User Auth (6h) + Start Lesson Mgmt (4h) | 20h |
|
||||||
|
| 2 | Lesson Mgmt (12h) | AI Services (16h) | 28h |
|
||||||
|
| 3 | Vocabulary (12h) + Quiz (6h) | AI Services (remaining 4h) + Story (8h) | 28h |
|
||||||
|
| 4 | Gamification (8h) + Frontend (8h) | Frontend (8h) + Testing | 24h |
|
||||||
|
|
||||||
|
### Solo Developer (8-10 weeks)
|
||||||
|
|
||||||
|
| Week | Focus | Hours |
|
||||||
|
|------|-------|-------|
|
||||||
|
| 1-2 | Infrastructure + Auth | 20h |
|
||||||
|
| 3-4 | Lesson Management + AI Services | 32h |
|
||||||
|
| 5 | Vocabulary + Quiz | 22h |
|
||||||
|
| 6 | Story Integration + Gamification | 20h |
|
||||||
|
| 7-8 | Frontend UI | 16h |
|
||||||
|
| 9-10 | Testing, Polish, Bug Fixes | 20h |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Quick Start Guide
|
||||||
|
|
||||||
|
### 1. Pick Your Starting Point
|
||||||
|
|
||||||
|
Based on your role:
|
||||||
|
|
||||||
|
| Role | Start With | Why |
|
||||||
|
|------|------------|-----|
|
||||||
|
| Backend Dev | Infrastructure Setup | Foundation for everything |
|
||||||
|
| Full-Stack | Infrastructure Setup | Need backend first |
|
||||||
|
| Frontend Dev | Wait for Phase 2 | Backend must be ready |
|
||||||
|
| DevOps | Infrastructure Setup | CI/CD, Docker setup |
|
||||||
|
| QA | Review all feature plans | Understand what to test |
|
||||||
|
|
||||||
|
### 2. Feature Implementation Checklist
|
||||||
|
|
||||||
|
For each feature:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Feature: [Name]
|
||||||
|
|
||||||
|
## Before Starting
|
||||||
|
- [ ] Read feature plan thoroughly
|
||||||
|
- [ ] Review dependencies - are they complete?
|
||||||
|
- [ ] Review risks - any blockers?
|
||||||
|
- [ ] Review tasks - understand scope
|
||||||
|
- [ ] Create branch: feature/[feature-name]
|
||||||
|
|
||||||
|
## During Implementation
|
||||||
|
- [ ] Follow Clean Architecture principles
|
||||||
|
- [ ] Write tests alongside code (TDD)
|
||||||
|
- [ ] Update feature plan with progress
|
||||||
|
- [ ] Document decisions in Notes & Decisions
|
||||||
|
- [ ] Commit frequently with Conventional Commits
|
||||||
|
|
||||||
|
## Before PR
|
||||||
|
- [ ] All tasks completed
|
||||||
|
- [ ] All acceptance criteria met
|
||||||
|
- [ ] All tests passing
|
||||||
|
- [ ] Code reviewed (self-review first)
|
||||||
|
- [ ] Update feature plan status to 🔄 Code Review
|
||||||
|
- [ ] Add PR link to feature plan
|
||||||
|
|
||||||
|
## After Merge
|
||||||
|
- [ ] Update feature plan status to ✅ Completed
|
||||||
|
- [ ] Add completion date
|
||||||
|
- [ ] Document lessons learned
|
||||||
|
- [ ] Update roadmap progress
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Daily Workflow
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start day
|
||||||
|
cd /home/lasserh/Projects/DeutschLernen
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Pick a feature
|
||||||
|
grep -l "🚀 In Progress" docs/features/*.md
|
||||||
|
|
||||||
|
# Work on tasks
|
||||||
|
# ... coding ...
|
||||||
|
|
||||||
|
# Check progress
|
||||||
|
grep -A 20 "## ✅ Tasks" docs/features/[feature-name].md
|
||||||
|
|
||||||
|
# End of day
|
||||||
|
# - Update task statuses
|
||||||
|
# - Update progress in feature plan
|
||||||
|
# - Push branch
|
||||||
|
git add .
|
||||||
|
git commit -m "feat([feature]): [description]"
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Current Features Status
|
||||||
|
|
||||||
|
### Phase 1: Foundation (Weeks 1-2)
|
||||||
|
|
||||||
|
| Feature | Status | Priority | Estimate | Assignee | Dependencies | Start Date | Target Completion |
|
||||||
|
|---------|--------|----------|----------|----------|--------------|------------|-------------------|
|
||||||
|
| [infrastructure-setup.md](infrastructure-setup.md) | ⏳ Planned | High | 10-14h | - | None | - | - |
|
||||||
|
| [user-authentication.md](user-authentication.md) | ⏳ Planned | High | 4-6h | - | Infrastructure | - | - |
|
||||||
|
|
||||||
|
### Phase 2: Core Backend (Weeks 3-4)
|
||||||
|
|
||||||
|
| Feature | Status | Priority | Estimate | Assignee | Dependencies | Start Date | Target Completion |
|
||||||
|
|---------|--------|----------|----------|----------|--------------|------------|-------------------|
|
||||||
|
| [lesson-management.md](lesson-management.md) | ⏳ Planned | High | 10-16h | - | Infrastructure, Auth | - | - |
|
||||||
|
| [ai-services.md](ai-services.md) | ⏳ Planned | High | 10-16h | - | Infrastructure | - | - |
|
||||||
|
| [vocabulary-system.md](vocabulary-system.md) | ⏳ Planned | High | 8-12h | - | Infrastructure, Lessons | - | - |
|
||||||
|
| [quiz-system.md](quiz-system.md) | ⏳ Planned | High | 6-10h | - | Infrastructure, Lessons | - | - |
|
||||||
|
|
||||||
|
### Phase 3: Content & Features (Weeks 5-6)
|
||||||
|
|
||||||
|
| Feature | Status | Priority | Estimate | Assignee | Dependencies | Start Date | Target Completion |
|
||||||
|
|---------|--------|----------|----------|----------|--------------|------------|-------------------|
|
||||||
|
| [story-integration.md](story-integration.md) | ⏳ Planned | High | 8-12h | - | Lessons, AI Services | - | - |
|
||||||
|
| [gamification.md](gamification.md) | ⏳ Planned | Medium | 6-8h | - | Auth, Lessons, Quiz | - | - |
|
||||||
|
|
||||||
|
### Phase 4: Frontend (Weeks 7-8)
|
||||||
|
|
||||||
|
| Feature | Status | Priority | Estimate | Assignee | Dependencies | Start Date | Target Completion |
|
||||||
|
|---------|--------|----------|----------|----------|--------------|------------|-------------------|
|
||||||
|
| [frontend-ui.md](frontend-ui.md) | ⏳ Planned | High | 10-16h | - | All backend features | - | - |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Quick Links
|
||||||
|
|
||||||
|
| Feature | Quick Access | Priority |
|
||||||
|
|---------|--------------|----------|
|
||||||
|
| Infrastructure Setup | [View](infrastructure-setup.md) | ⭐⭐⭐⭐⭐ |
|
||||||
|
| User Authentication | [View](user-authentication.md) | ⭐⭐⭐⭐⭐ |
|
||||||
|
| Lesson Management | [View](lesson-management.md) | ⭐⭐⭐⭐⭐ |
|
||||||
|
| AI Services | [View](ai-services.md) | ⭐⭐⭐⭐⭐ |
|
||||||
|
| Vocabulary System | [View](vocabulary-system.md) | ⭐⭐⭐⭐ |
|
||||||
|
| Quiz System | [View](quiz-system.md) | ⭐⭐⭐⭐ |
|
||||||
|
| Story Integration | [View](story-integration.md) | ⭐⭐⭐⭐ |
|
||||||
|
| Gamification | [View](gamification.md) | ⭐⭐⭐ |
|
||||||
|
| Frontend UI | [View](frontend-ui.md) | ⭐⭐⭐⭐ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 Progress Tracking Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all features
|
||||||
|
ls -1 docs/features/*.md | grep -v README | grep -v template
|
||||||
|
|
||||||
|
# Count features by status
|
||||||
|
for status in "Planned" "In Progress" "Code Review" "Completed"; do
|
||||||
|
echo "$status: $(grep -l "Status.*$status" docs/features/*.md | wc -l)"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Find features ready to start (dependencies met)
|
||||||
|
# (This requires manual checking against dependency list)
|
||||||
|
|
||||||
|
# Get total estimated hours
|
||||||
|
grep "Estimate:" docs/features/*.md | grep -oP "\d+-\d+h" | \
|
||||||
|
awk -F'-' '{sum+=$1+$2} END {print "Total estimate: " sum/2 " hours"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Best Practices
|
||||||
|
|
||||||
|
1. **Start with Infrastructure** - Everything depends on it
|
||||||
|
2. **Complete dependencies first** - Don't get blocked mid-feature
|
||||||
|
3. **Update as you go** - Keep feature plans in sync with progress
|
||||||
|
4. **Test as you build** - Follow the TDD approach in the application plan
|
||||||
|
5. **Document decisions** - Future you will thank present you
|
||||||
|
6. **Review before merging** - Use the Definition of Done as a checklist
|
||||||
|
7. **Celebrate completions** - Update status to ✅ and reflect on lessons learned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Related Documentation
|
||||||
|
|
||||||
|
- [AGENTS.md](../AGENTS.md) - Development rules and workflows
|
||||||
|
- [Application Plan](../architecture/application-plan.md) - Overall project vision
|
||||||
|
- [Backend Structure](../architecture/backend-structure.md) - Technical architecture
|
||||||
|
- [Frontend Structure](../architecture/frontend-structure.md) - Frontend architecture
|
||||||
|
- [Database Schema](../database/initial-database-schema.sql) - Database design
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: May 31, 2025*
|
||||||
|
*Feature tracking system based on Clean Architecture and TDD principles*
|
||||||
896
docs/features/ai-services.md
Normal file
896
docs/features/ai-services.md
Normal file
|
|
@ -0,0 +1,896 @@
|
||||||
|
# Feature: AI Services Integration
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: High
|
||||||
|
> **Estimate**: 10-16 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Story Integration, Vocabulary System, Quiz System, Lesson Management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Integrate three AI services into the application: Mistral-Medium for text generation (stories, feedback), Vosk for speech recognition (speaking exercises), and Coqui TTS for text-to-speech (vocabulary, stories, quizzes).
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a learner, I want AI-powered features like generated stories, speech recognition for speaking practice, and TTS for audio content so that I can have an immersive and interactive learning experience.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Mistral-Medium API is integrated for story generation
|
||||||
|
- [ ] Mistral-Medium API is integrated for writing feedback
|
||||||
|
- [ ] Vosk speech recognition is integrated for speaking exercises
|
||||||
|
- [ ] Coqui TTS is integrated for audio generation
|
||||||
|
- [ ] All AI services are configurable via appsettings.json
|
||||||
|
- [ ] Error handling for AI service failures
|
||||||
|
- [ ] Rate limiting/caching for AI API calls
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | Generate stories using Mistral-Medium | High |
|
||||||
|
| FR-002 | Generate writing feedback using Mistral-Medium | High |
|
||||||
|
| FR-003 | Transcribe speech using Vosk | High |
|
||||||
|
| FR-004 | Generate audio using Coqui TTS | High |
|
||||||
|
| FR-005 | Configure all services via configuration | High |
|
||||||
|
| FR-006 | Handle AI service errors gracefully | High |
|
||||||
|
| FR-007 | Cache/rate limit AI API calls | Medium |
|
||||||
|
| FR-008 | Validate AI outputs before use | Medium |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: TTS generation < 2 seconds per sentence
|
||||||
|
- Performance: Speech recognition < 3 seconds
|
||||||
|
- Performance: AI API calls < 5 seconds
|
||||||
|
- Reliability: Services should degrade gracefully on failure
|
||||||
|
- Cost: Minimize API call costs (caching, batching)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Architecture Overview
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ AI Services Layer │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||||
|
│ │ Mistral-Medium │ │ Vosk │ │ Coqui TTS │ │
|
||||||
|
│ │ (Text Gen) │ │ (Speech Recog.) │ │ (Audio Gen) │ │
|
||||||
|
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Application Services │ │
|
||||||
|
│ │ - StoryGenerationService │ │
|
||||||
|
│ │ - WritingFeedbackService │ │
|
||||||
|
│ │ - VoskService (Speech Recognition) │ │
|
||||||
|
│ │ - TtsService (Text-to-Speech) │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend Services**:
|
||||||
|
- `IMistralService` / `MistralService` - Text generation
|
||||||
|
- `IVoskService` / `VoskService` - Speech recognition
|
||||||
|
- `ITtsService` / `TtsService` - Text-to-speech
|
||||||
|
- **Configuration**: appsettings.json with AI settings
|
||||||
|
- **External Dependencies**:
|
||||||
|
- Mistral-Medium API
|
||||||
|
- Vosk Python library + German model
|
||||||
|
- Coqui TTS Python library + German model
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
|
||||||
|
#### Story Generation Flow
|
||||||
|
```
|
||||||
|
1. StoryGenerationService receives request with vocabulary list and level
|
||||||
|
2. Service constructs prompt for Mistral-Medium
|
||||||
|
3. MistralService sends prompt to Mistral API
|
||||||
|
4. Mistral API returns generated story text
|
||||||
|
5. StoryGenerationService validates and returns story
|
||||||
|
6. StoryService saves story and triggers audio generation
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Speech Recognition Flow
|
||||||
|
```
|
||||||
|
1. User records speech in frontend
|
||||||
|
2. Frontend sends audio file to /api/speech/recognize
|
||||||
|
3. VoskService receives audio bytes
|
||||||
|
4. VoskService calls Vosk Python CLI with German model
|
||||||
|
5. Vosk returns transcribed text
|
||||||
|
6. Backend validates transcription and returns to frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
#### TTS Flow
|
||||||
|
```
|
||||||
|
1. TtsService receives text to synthesize
|
||||||
|
2. Service calls Coqui TTS Python CLI
|
||||||
|
3. Coqui generates audio file
|
||||||
|
4. Audio file saved to filesystem
|
||||||
|
5. Audio URL returned to caller
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Configuration & Interfaces (2 hours)
|
||||||
|
- [ ] Add AI configuration section to appsettings.json
|
||||||
|
- [ ] Create configuration classes (MistralConfig, VoskConfig, CoquiConfig)
|
||||||
|
- [ ] Define service interfaces (IMistralService, IVoskService, ITtsService)
|
||||||
|
- [ ] Register services in Program.cs
|
||||||
|
- [ ] Set up configuration validation
|
||||||
|
|
||||||
|
### Phase 2: Mistral-Medium Integration (2-3 hours)
|
||||||
|
- [ ] Create MistralService implementation
|
||||||
|
- [ ] Implement Mistral API client
|
||||||
|
- [ ] Create request/response models
|
||||||
|
- [ ] Implement retry logic for API calls
|
||||||
|
- [ ] Add rate limiting (e.g., max 10 requests/minute)
|
||||||
|
- [ ] Add response caching for similar prompts
|
||||||
|
- [ ] Create prompt templates for different use cases
|
||||||
|
|
||||||
|
### Phase 3: Vosk Speech Recognition (2-3 hours)
|
||||||
|
- [ ] Create VoskService implementation
|
||||||
|
- [ ] Set up Vosk Python environment
|
||||||
|
- [ ] Download and configure German model (vosk-model-de-0.22)
|
||||||
|
- [ ] Implement audio processing
|
||||||
|
- [ ] Handle different audio formats
|
||||||
|
- [ ] Add error handling for recognition failures
|
||||||
|
- [ ] Create /api/speech/recognize endpoint
|
||||||
|
|
||||||
|
### Phase 4: Coqui TTS Integration (2-3 hours)
|
||||||
|
- [ ] Create TtsService implementation
|
||||||
|
- [ ] Set up Coqui TTS Python environment
|
||||||
|
- [ ] Download and configure German model
|
||||||
|
- [ ] Implement audio generation
|
||||||
|
- [ ] Add audio file management (storage, cleanup)
|
||||||
|
- [ ] Create audio serving endpoints
|
||||||
|
- [ ] Implement batch audio generation
|
||||||
|
|
||||||
|
### Phase 5: Service Integration (2 hours)
|
||||||
|
- [ ] Create StoryGenerationService (uses MistralService)
|
||||||
|
- [ ] Create WritingFeedbackService (uses MistralService)
|
||||||
|
- [ ] Create SpeechExerciseService (uses VoskService)
|
||||||
|
- [ ] Create AudioGenerationService (uses TtsService)
|
||||||
|
- [ ] Add health checks for all AI services
|
||||||
|
- [ ] Implement fallback mechanisms for service failures
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Configuration & Interfaces | - | ⏳ |
|
||||||
|
| Mistral Integration | - | ⏳ |
|
||||||
|
| Vosk Integration | - | ⏳ |
|
||||||
|
| Coqui TTS Integration | - | ⏳ |
|
||||||
|
| Service Integration | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend - Configuration
|
||||||
|
- [ ] Add Mistral settings to appsettings.json
|
||||||
|
- [ ] Add Vosk settings to appsettings.json
|
||||||
|
- [ ] Add Coqui settings to appsettings.json
|
||||||
|
- [ ] Create Configuration/MistralConfig.cs
|
||||||
|
- [ ] Create Configuration/VoskConfig.cs
|
||||||
|
- [ ] Create Configuration/CoquiConfig.cs
|
||||||
|
- [ ] Register all AI services in Program.cs
|
||||||
|
- [ ] Add health checks for AI services
|
||||||
|
|
||||||
|
### Backend - Mistral Service
|
||||||
|
- [ ] Create Domain/Interfaces/IMistralService.cs
|
||||||
|
- [ ] Create Infrastructure/Services/MistralService.cs
|
||||||
|
- [ ] Implement Mistral API client
|
||||||
|
- [ ] Create Models/MistralRequest.cs
|
||||||
|
- [ ] Create Models/MistralResponse.cs
|
||||||
|
- [ ] Add retry logic
|
||||||
|
- [ ] Add rate limiting
|
||||||
|
- [ ] Add response caching
|
||||||
|
- [ ] Write unit tests
|
||||||
|
|
||||||
|
### Backend - Vosk Service
|
||||||
|
- [ ] Create Domain/Interfaces/IVoskService.cs
|
||||||
|
- [ ] Create Infrastructure/Services/VoskService.cs
|
||||||
|
- [ ] Set up Python process execution
|
||||||
|
- [ ] Download and configure vosk-model-de-0.22
|
||||||
|
- [ ] Implement audio recognition
|
||||||
|
- [ ] Create /api/speech/recognize endpoint
|
||||||
|
- [ ] Create Presentation/Controllers/SpeechController.cs
|
||||||
|
- [ ] Write unit tests
|
||||||
|
|
||||||
|
### Backend - Coqui TTS Service
|
||||||
|
- [ ] Create Domain/Interfaces/ITtsService.cs
|
||||||
|
- [ ] Create Infrastructure/Services/TtsService.cs
|
||||||
|
- [ ] Set up Python process execution
|
||||||
|
- [ ] Download and configure Coqui German model
|
||||||
|
- [ ] Implement audio generation
|
||||||
|
- [ ] Create audio file storage mechanism
|
||||||
|
- [ ] Create /api/tts/generate endpoint
|
||||||
|
- [ ] Create Presentation/Controllers/TtsController.cs
|
||||||
|
- [ ] Write unit tests
|
||||||
|
|
||||||
|
### Backend - Higher-Level Services
|
||||||
|
- [ ] Create Application/Services/StoryGenerationService.cs
|
||||||
|
- [ ] Create Application/Services/WritingFeedbackService.cs
|
||||||
|
- [ ] Integrate with MistralService
|
||||||
|
- [ ] Add validation for AI outputs
|
||||||
|
- [ ] Write integration tests
|
||||||
|
|
||||||
|
### Infrastructure Setup
|
||||||
|
- [ ] Install Python 3.8+
|
||||||
|
- [ ] Install Vosk Python package
|
||||||
|
- [ ] Download vosk-model-de-0.22
|
||||||
|
- [ ] Install Coqui TTS package
|
||||||
|
- [ ] Download Coqui German model
|
||||||
|
- [ ] Set up file storage for audio
|
||||||
|
- [ ] Configure permissions
|
||||||
|
|
||||||
|
### Frontend Integration
|
||||||
|
- [ ] Create services/speechService.ts
|
||||||
|
- [ ] Create services/ttsService.ts
|
||||||
|
- [ ] Create services/aiService.ts
|
||||||
|
- [ ] Integrate with Recorder component
|
||||||
|
- [ ] Integrate with AudioPlayer component
|
||||||
|
- [ ] Add error handling for AI failures
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### AI-Specific Criteria
|
||||||
|
- [ ] All AI services functional in development
|
||||||
|
- [ ] Mistral API integration tested with valid API key
|
||||||
|
- [ ] Vosk speech recognition tested with German model
|
||||||
|
- [ ] Coqui TTS tested with German model
|
||||||
|
- [ ] Error handling tested (invalid inputs, service failures)
|
||||||
|
- [ ] Fallback mechanisms implemented and tested
|
||||||
|
- [ ] Rate limiting configured and tested
|
||||||
|
- [ ] Audio file generation and storage verified
|
||||||
|
- [ ] Health checks for all AI services passing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
| Load Testing | AI service performance | k6/JMeter | DevOps |
|
||||||
|
|
||||||
|
### AI-Specific Tests
|
||||||
|
|
||||||
|
#### Mistral Service Tests
|
||||||
|
- [ ] Test successful text generation
|
||||||
|
- [ ] Test API error handling (429, 500, 503)
|
||||||
|
- [ ] Test rate limiting (max requests per minute)
|
||||||
|
- [ ] Test response caching
|
||||||
|
- [ ] Test retry logic on failures
|
||||||
|
- [ ] Test timeout handling
|
||||||
|
- [ ] Test invalid API key handling
|
||||||
|
|
||||||
|
#### Vosk Service Tests
|
||||||
|
- [ ] Test successful speech recognition (clear audio)
|
||||||
|
- [ ] Test speech recognition with background noise
|
||||||
|
- [ ] Test speech recognition with different accents
|
||||||
|
- [ ] Test empty audio handling
|
||||||
|
- [ ] Test invalid audio format handling
|
||||||
|
- [ ] Test Python process failure handling
|
||||||
|
- [ ] Test model not found error handling
|
||||||
|
- [ ] Test confidence threshold validation
|
||||||
|
|
||||||
|
#### Coqui TTS Service Tests
|
||||||
|
- [ ] Test successful audio generation
|
||||||
|
- [ ] Test audio generation with long text
|
||||||
|
- [ ] Test audio generation with special characters
|
||||||
|
- [ ] Test invalid text handling
|
||||||
|
- [ ] Test Python process failure handling
|
||||||
|
- [ ] Test model not found error handling
|
||||||
|
- [ ] Test audio file format validation
|
||||||
|
- [ ] Test audio quality validation
|
||||||
|
|
||||||
|
### Test Data
|
||||||
|
- Sample audio files for Vosk testing (clear German speech, noisy audio, non-German speech)
|
||||||
|
- Sample texts for TTS testing (short, long, with special characters, with German umlauts)
|
||||||
|
- Sample prompts for Mistral testing (A1, A2, B1 levels)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚨 Risks & Mitigations
|
||||||
|
|
||||||
|
### Technical Risks
|
||||||
|
|
||||||
|
| Risk | Likelihood | Impact | Mitigation | Owner |
|
||||||
|
|------|------------|--------|------------|-------|
|
||||||
|
| Python-.NET integration failures | High | High | Use Process class with proper error handling, implement process pooling, add timeouts | Backend Dev |
|
||||||
|
| Vosk model compatibility issues | Medium | High | Test with vosk-model-de-0.22 before implementation, have fallback to vosk-model-small-de-0.15 | Backend Dev |
|
||||||
|
| Coqui model quality issues | Medium | Medium | Test with sample German text, have alternative TTS service as fallback | Backend Dev |
|
||||||
|
| Mistral API rate limits | High | Medium | Implement caching (1h TTL), request queue, exponential backoff | Backend Dev |
|
||||||
|
| Mistral API costs exceed budget | Medium | High | Set budget alerts, implement cost tracking, cache aggressively | Backend Dev |
|
||||||
|
| AI services slow performance | High | Medium | Implement async processing, use background jobs for batch operations | Backend Dev |
|
||||||
|
| Audio files too large | Medium | Medium | Compress audio (16kHz, mono), implement streaming for large files | Backend Dev |
|
||||||
|
| Model files too large for deployment | Medium | Medium | Use Docker volumes, separate storage for models, consider cloud storage | DevOps |
|
||||||
|
| Memory leaks in Python processes | Medium | High | Implement process lifecycle management, add memory monitoring, use process pooling | Backend Dev |
|
||||||
|
| Different Python versions cause issues | Medium | Medium | Use Docker to pin Python version, document exact version in README | DevOps |
|
||||||
|
|
||||||
|
### Operational Risks
|
||||||
|
|
||||||
|
| Risk | Likelihood | Impact | Mitigation | Owner |
|
||||||
|
|------|------------|--------|------------|-------|
|
||||||
|
| AI service downtime | Medium | High | Implement health checks, circuit breakers, fallback responses | DevOps |
|
||||||
|
| Model files corrupted | Low | High | Implement checksum validation, store backups, automated recovery | DevOps |
|
||||||
|
| API key exposure | Medium | High | Use GitHub secrets, Azure Key Vault, never commit to repo | Security |
|
||||||
|
| Audio storage fills up | Medium | Medium | Implement cleanup job, set size quotas, use cloud storage | DevOps |
|
||||||
|
|
||||||
|
### Business Risks
|
||||||
|
|
||||||
|
| Risk | Likelihood | Impact | Mitigation | Owner |
|
||||||
|
|------|------------|--------|------------|-------|
|
||||||
|
| User data privacy concerns | Medium | High | Anonymize audio before processing, document data handling policy, comply with GDPR | Legal |
|
||||||
|
| AI generates inappropriate content | Low | High | Implement content moderation, add user reporting, use system prompts to prevent | Backend Dev |
|
||||||
|
| AI services become too expensive | Medium | Medium | Monitor costs, set budget caps, evaluate open-source alternatives | Product |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required (backend project)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Python 3.8+
|
||||||
|
- Vosk Python library
|
||||||
|
- vosk-model-de-0.22 (German model)
|
||||||
|
- Coqui TTS Python library
|
||||||
|
- Coqui German TTS model
|
||||||
|
- Mistral-Medium API key
|
||||||
|
|
||||||
|
### External Services
|
||||||
|
| Service | Purpose | Configuration |
|
||||||
|
|---------|---------|---------------|
|
||||||
|
| Mistral-Medium API | Text generation (stories, feedback) | API key, endpoint URL |
|
||||||
|
| Vosk | Speech recognition | Python path, model path |
|
||||||
|
| Coqui TTS | Text-to-speech | Python path, model name |
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete
|
||||||
|
- [ ] Python environment must be configured
|
||||||
|
- [ ] AI models must be downloaded
|
||||||
|
- [ ] Mistral API key must be obtained
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Technical Deep Dive: Python-.NET Integration
|
||||||
|
|
||||||
|
### Integration Patterns
|
||||||
|
|
||||||
|
#### Option 1: Process.Start (Recommended for MVP)
|
||||||
|
```csharp
|
||||||
|
// Simple approach - spawn Python process for each request
|
||||||
|
public async Task<string> RecognizeSpeechAsync(byte[] audioData)
|
||||||
|
{
|
||||||
|
var tempFile = Path.GetTempFileName() + ".wav";
|
||||||
|
await File.WriteAllBytesAsync(tempFile, audioData);
|
||||||
|
|
||||||
|
var process = new Process
|
||||||
|
{
|
||||||
|
StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "python",
|
||||||
|
Arguments = $"-m vosk.transcribe --model {_modelPath} --input {tempFile}",
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
// Prevent process from hanging
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["PYTHONPATH"] = "/path/to/vosk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
// Read output with timeout
|
||||||
|
var output = await process.StandardOutput.ReadToEndAsync();
|
||||||
|
var error = await process.StandardError.ReadToEndAsync();
|
||||||
|
|
||||||
|
await process.WaitForExitAsync();
|
||||||
|
|
||||||
|
if (process.ExitCode != 0)
|
||||||
|
{
|
||||||
|
throw new AiServiceException($"Vosk failed: {error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.Trim();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pros:** Simple, easy to implement, no additional dependencies
|
||||||
|
**Cons:** Process startup overhead (~100-500ms per call), resource-intensive
|
||||||
|
|
||||||
|
#### Option 2: Process Pooling (Recommended for Production)
|
||||||
|
```csharp
|
||||||
|
// Maintain a pool of persistent Python processes
|
||||||
|
public class PythonProcessPool : IDisposable
|
||||||
|
{
|
||||||
|
private readonly ConcurrentQueue<Process> _pool = new();
|
||||||
|
private readonly SemaphoreSlim _semaphore;
|
||||||
|
private readonly string _pythonPath;
|
||||||
|
private readonly string _scriptPath;
|
||||||
|
|
||||||
|
public PythonProcessPool(int size, string pythonPath, string scriptPath)
|
||||||
|
{
|
||||||
|
_semaphore = new SemaphoreSlim(size);
|
||||||
|
_pythonPath = pythonPath;
|
||||||
|
_scriptPath = scriptPath;
|
||||||
|
|
||||||
|
// Pre-warm the pool
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
_pool.Enqueue(StartProcess());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> ExecuteAsync(string input)
|
||||||
|
{
|
||||||
|
await _semaphore.WaitAsync();
|
||||||
|
|
||||||
|
if (!_pool.TryDequeue(out var process))
|
||||||
|
{
|
||||||
|
process = StartProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Send input to stdin
|
||||||
|
await process.StandardInput.WriteLineAsync(input);
|
||||||
|
await process.StandardInput.FlushAsync();
|
||||||
|
|
||||||
|
// Read response from stdout
|
||||||
|
var response = await process.StandardOutput.ReadLineAsync();
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_pool.Enqueue(process);
|
||||||
|
_semaphore.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Process StartProcess()
|
||||||
|
{
|
||||||
|
return new Process
|
||||||
|
{
|
||||||
|
StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = _pythonPath,
|
||||||
|
Arguments = _scriptPath,
|
||||||
|
RedirectStandardInput = true,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true
|
||||||
|
}
|
||||||
|
}.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var process in _pool)
|
||||||
|
{
|
||||||
|
try { process.Kill(); } catch { }
|
||||||
|
process.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pros:** Eliminates process startup overhead, much faster for repeated calls
|
||||||
|
**Cons:** More complex, need to handle process lifecycle, stdin/stdout parsing
|
||||||
|
|
||||||
|
#### Option 3: gRPC (Best for Production)
|
||||||
|
- Create Python gRPC server for AI services
|
||||||
|
- .NET client calls gRPC methods
|
||||||
|
- Single persistent Python process
|
||||||
|
- Type-safe, high-performance
|
||||||
|
|
||||||
|
**Pros:** Best performance, type-safe, production-ready
|
||||||
|
**Cons:** Most complex to set up, requires gRPC knowledge
|
||||||
|
|
||||||
|
### Error Handling Strategy
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Comprehensive error handling for AI services
|
||||||
|
public async Task<T> ExecuteWithRetryAsync<T>(
|
||||||
|
Func<Task<T>> action,
|
||||||
|
string operationName,
|
||||||
|
int maxRetries = 3,
|
||||||
|
TimeSpan? timeout = null)
|
||||||
|
{
|
||||||
|
var retryCount = 0;
|
||||||
|
timeout ??= TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var cts = new CancellationTokenSource(timeout.Value);
|
||||||
|
return await action();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) when (retryCount < maxRetries)
|
||||||
|
{
|
||||||
|
retryCount++;
|
||||||
|
var delay = TimeSpan.FromSeconds(Math.Pow(2, retryCount));
|
||||||
|
_logger.LogWarning(
|
||||||
|
"{Operation} timed out (attempt {Attempt}), retrying in {Delay}s...",
|
||||||
|
operationName, retryCount, delay.TotalSeconds);
|
||||||
|
await Task.Delay(delay);
|
||||||
|
}
|
||||||
|
catch (AiServiceException ex) when (IsRetryable(ex) && retryCount < maxRetries)
|
||||||
|
{
|
||||||
|
retryCount++;
|
||||||
|
var delay = TimeSpan.FromSeconds(Math.Pow(2, retryCount));
|
||||||
|
_logger.LogWarning(ex,
|
||||||
|
"{Operation} failed (attempt {Attempt}), retrying in {Delay}s...",
|
||||||
|
operationName, retryCount, delay.TotalSeconds);
|
||||||
|
await Task.Delay(delay);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Operation} failed permanently after {Attempts} attempts",
|
||||||
|
operationName, retryCount + 1);
|
||||||
|
throw new AiServiceException($"{operationName} failed: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRetryable(AiServiceException ex) =>
|
||||||
|
ex.ErrorCode switch
|
||||||
|
{
|
||||||
|
AiErrorCode.RateLimited => true,
|
||||||
|
AiErrorCode.Temporary => true,
|
||||||
|
AiErrorCode.Timeout => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Health Check Implementation
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Health check for AI services
|
||||||
|
public class AiServicesHealthCheck : IHealthCheck
|
||||||
|
{
|
||||||
|
private readonly IMistralService _mistral;
|
||||||
|
private readonly IVoskService _vosk;
|
||||||
|
private readonly ITtsService _tts;
|
||||||
|
|
||||||
|
public async Task<HealthCheckResult> CheckHealthAsync(
|
||||||
|
HealthCheckContext context,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var checks = new Dictionary<string, HealthStatus>();
|
||||||
|
|
||||||
|
// Check Mistral
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _mistral.TestConnectionAsync(cancellationToken);
|
||||||
|
checks["Mistral"] = HealthStatus.Healthy;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
checks["Mistral"] = HealthStatus.Unhealthy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Vosk
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _vosk.TestModelAsync(cancellationToken);
|
||||||
|
checks["Vosk"] = HealthStatus.Healthy;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
checks["Vosk"] = HealthStatus.Unhealthy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Coqui TTS
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _tts.TestModelAsync(cancellationToken);
|
||||||
|
checks["Coqui TTS"] = HealthStatus.Healthy;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
checks["Coqui TTS"] = HealthStatus.Unhealthy;
|
||||||
|
}
|
||||||
|
|
||||||
|
var allHealthy = checks.Values.All(s => s == HealthStatus.Healthy);
|
||||||
|
var status = allHealthy ? HealthStatus.Healthy : HealthStatus.Unhealthy;
|
||||||
|
|
||||||
|
return new HealthCheckResult(
|
||||||
|
status,
|
||||||
|
"AI Services health check",
|
||||||
|
data: checks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audio File Management
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Audio file storage service
|
||||||
|
public class AudioFileService
|
||||||
|
{
|
||||||
|
private readonly string _basePath;
|
||||||
|
private readonly ILogger<AudioFileService> _logger;
|
||||||
|
|
||||||
|
public AudioFileService(IConfiguration config, ILogger<AudioFileService> logger)
|
||||||
|
{
|
||||||
|
_basePath = config["Audio:StoragePath"] ?? "/var/audio";
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
Directory.CreateDirectory(_basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> SaveAudioAsync(byte[] audioData, string category, int entityId)
|
||||||
|
{
|
||||||
|
// Validate audio data
|
||||||
|
if (audioData == null || audioData.Length == 0)
|
||||||
|
throw new ArgumentException("Audio data cannot be empty");
|
||||||
|
|
||||||
|
if (audioData.Length > 10 * 1024 * 1024) // 10MB limit
|
||||||
|
throw new ArgumentException("Audio file too large");
|
||||||
|
|
||||||
|
// Create category directory
|
||||||
|
var categoryPath = Path.Combine(_basePath, category);
|
||||||
|
Directory.CreateDirectory(categoryPath);
|
||||||
|
|
||||||
|
// Generate unique filename
|
||||||
|
var extension = ".wav"; // or detect from data
|
||||||
|
var filename = $"{entityId}{extension}";
|
||||||
|
var fullPath = Path.Combine(categoryPath, filename);
|
||||||
|
|
||||||
|
// Check for existing file
|
||||||
|
if (File.Exists(fullPath))
|
||||||
|
File.Delete(fullPath);
|
||||||
|
|
||||||
|
// Save file
|
||||||
|
await File.WriteAllBytesAsync(fullPath, audioData);
|
||||||
|
|
||||||
|
// Return relative path
|
||||||
|
return $"/audio/{category}/{filename}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CleanupOldFilesAsync(TimeSpan olderThan)
|
||||||
|
{
|
||||||
|
var cutoff = DateTime.UtcNow - olderThan;
|
||||||
|
|
||||||
|
foreach (var categoryDir in Directory.GetDirectories(_basePath))
|
||||||
|
{
|
||||||
|
foreach (var file in Directory.GetFiles(categoryDir))
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(file);
|
||||||
|
if (fileInfo.LastWriteTimeUtc < cutoff)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
_logger.LogInformation("Deleted old audio file: {File}", file);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to delete audio file: {File}", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rate Limiting Implementation
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Rate limiter for AI services
|
||||||
|
public class AiRateLimiter
|
||||||
|
{
|
||||||
|
private readonly ConcurrentDictionary<string, RateLimitEntry> _limits = new();
|
||||||
|
private readonly int _maxRequests;
|
||||||
|
private readonly TimeSpan _window;
|
||||||
|
|
||||||
|
public AiRateLimiter(int maxRequestsPerWindow, TimeSpan window)
|
||||||
|
{
|
||||||
|
_maxRequests = maxRequestsPerWindow;
|
||||||
|
_window = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryAcquire(string serviceName)
|
||||||
|
{
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
var entry = _limits.GetOrAdd(serviceName, _ => new RateLimitEntry());
|
||||||
|
|
||||||
|
lock (entry)
|
||||||
|
{
|
||||||
|
// Remove old requests
|
||||||
|
entry.Requests.RemoveAll(r => now - r > _window);
|
||||||
|
|
||||||
|
// Check if limit exceeded
|
||||||
|
if (entry.Requests.Count >= _maxRequests)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Add new request
|
||||||
|
entry.Requests.Add(now);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RateLimitEntry
|
||||||
|
{
|
||||||
|
public List<DateTime> Requests { get; } = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage in controller
|
||||||
|
[HttpPost("recognize")]
|
||||||
|
public async Task<IActionResult> RecognizeSpeech([FromBody] AudioRequest request)
|
||||||
|
{
|
||||||
|
if (!_rateLimiter.TryAcquire("Vosk"))
|
||||||
|
{
|
||||||
|
return StatusCode(429, "Too many requests");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... process request
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Use Mistral-Medium | Best balance of quality and cost for this use case |
|
||||||
|
| May 31, 2025 | Use Vosk for speech recognition | Open-source, supports German, self-hostable |
|
||||||
|
| May 31, 2025 | Use Coqui TTS | Open-source, good quality, supports German |
|
||||||
|
| May 31, 2025 | Self-host AI services | More control, no external API dependencies (except Mistral) |
|
||||||
|
| May 31, 2025 | Use Python CLI wrappers | Easier integration with .NET, well-supported libraries |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
|
||||||
|
#### Vosk Configuration
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Vosk": {
|
||||||
|
"PythonPath": "/usr/bin/python3",
|
||||||
|
"ModelPath": "/models/vosk-model-de-0.22",
|
||||||
|
"SampleRate": 16000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Coqui TTS Configuration
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Coqui": {
|
||||||
|
"PythonPath": "/usr/bin/python3",
|
||||||
|
"ModelName": "tts_models/de/deu/fairseq/vits",
|
||||||
|
"AudioOutputFormat": "wav",
|
||||||
|
"SampleRate": 22050
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Mistral Configuration
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Mistral": {
|
||||||
|
"ApiKey": "your-api-key",
|
||||||
|
"BaseUrl": "https://api.mistral.ai/v1/",
|
||||||
|
"DefaultModel": "mistral-medium",
|
||||||
|
"TimeoutSeconds": 30,
|
||||||
|
"MaxRetries": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling Strategy
|
||||||
|
1. **Transient errors**: Retry with exponential backoff
|
||||||
|
2. **Rate limits**: Return 429 to client, suggest retry
|
||||||
|
3. **Service unavailable**: Return 503, log error
|
||||||
|
4. **Invalid response**: Validate output, return meaningful error
|
||||||
|
5. **Timeout**: Return 504, suggest retry
|
||||||
|
|
||||||
|
### Caching Strategy
|
||||||
|
- **Mistral responses**: Cache for 1 hour (stories unlikely to change)
|
||||||
|
- **TTS audio**: Cache files permanently (regenerate only if text changes)
|
||||||
|
- **Vosk**: No caching (each audio is unique)
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Vosk model is ~500MB - ensure enough disk space
|
||||||
|
- ⚠️ Coqui model is ~1.5GB - ensure enough disk space
|
||||||
|
- ⚠️ Python processes may have memory leaks - monitor and restart
|
||||||
|
- ⚠️ AI services may fail silently - implement health checks
|
||||||
|
- ⚠️ Mistral API has costs - implement budget tracking
|
||||||
|
- ⚠️ Audio generation can be CPU-intensive - consider separate service
|
||||||
|
- ⚠️ Different Python versions may have compatibility issues
|
||||||
|
|
||||||
|
### File Storage Structure
|
||||||
|
```
|
||||||
|
/public/
|
||||||
|
├── audio/
|
||||||
|
│ ├── vocabulary/ # Vocabulary word audio
|
||||||
|
│ │ └── {id}.wav
|
||||||
|
│ ├── story/ # Story segment audio
|
||||||
|
│ │ └── {levelId}-{order}.wav
|
||||||
|
│ └── quiz/ # Quiz question audio
|
||||||
|
│ └── {questionId}.wav
|
||||||
|
└── models/ # AI models
|
||||||
|
├── vosk/
|
||||||
|
│ └── vosk-model-de-0.22/
|
||||||
|
└── coqui/
|
||||||
|
└── tts_models/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Considerations
|
||||||
|
- TTS generation: ~1-2 seconds per sentence
|
||||||
|
- Speech recognition: ~1-3 seconds per audio clip
|
||||||
|
- Mistral API: ~2-5 seconds per request
|
||||||
|
- Consider async/background processing for batch operations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Feature: [Story Integration](story-integration.md)
|
||||||
|
- Feature: [Vocabulary System](vocabulary-system.md)
|
||||||
|
- Feature: [Quiz System](quiz-system.md)
|
||||||
|
- Reference: [Mistral AI API Docs](https://docs.mistral.ai/)
|
||||||
|
- Reference: [Vosk Documentation](https://alphacephei.com/vosk/)
|
||||||
|
- Reference: [Coqui TTS GitHub](https://github.com/coqui-ai/TTS)
|
||||||
|
- Reference: [vosk-model-de-0.22](https://alphacephei.com/vosk/models)
|
||||||
|
- Reference: [Coqui German Model](https://github.com/coqui-ai/TTS/wiki/Multilingual-support)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
605
docs/features/frontend-ui.md
Normal file
605
docs/features/frontend-ui.md
Normal file
|
|
@ -0,0 +1,605 @@
|
||||||
|
# Feature: Frontend UI & Components
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: High
|
||||||
|
> **Estimate**: 10-16 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, User Authentication, Lesson Management, Vocabulary System, Quiz System, Story Integration, AI Services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement the React + TypeScript frontend application with all UI components, pages, hooks, and services needed for the German learning web app.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a user, I want a responsive, intuitive, and visually appealing web interface so that I can easily navigate the application, access learning content, and track my progress.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] React application with TypeScript and Vite
|
||||||
|
- [ ] Responsive design (mobile-first)
|
||||||
|
- [ ] All pages and components implemented
|
||||||
|
- [ ] State management configured
|
||||||
|
- [ ] API client for backend communication
|
||||||
|
- [ ] Audio playback and recording functionality
|
||||||
|
- [ ] Authentication flow integrated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | React 19 + TypeScript + Vite setup | High |
|
||||||
|
| FR-002 | Mobile-first responsive design | High |
|
||||||
|
| FR-003 | Dashboard page with progress | High |
|
||||||
|
| FR-004 | Lesson pages with all tabs | High |
|
||||||
|
| FR-005 | Quiz pages with all question types | High |
|
||||||
|
| FR-006 | Story pages with audio | High |
|
||||||
|
| FR-007 | Practice pages for speaking/writing | High |
|
||||||
|
| FR-008 | Profile page | Medium |
|
||||||
|
| FR-009 | Login/Registration pages | High |
|
||||||
|
| FR-010 | Audio player component | High |
|
||||||
|
| FR-011 | Audio recorder component | High |
|
||||||
|
| FR-012 | API client service | High |
|
||||||
|
| FR-013 | Authentication context | High |
|
||||||
|
| FR-014 | Form handling and validation | Medium |
|
||||||
|
| FR-015 | Error handling and notifications | Medium |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Pages load in < 2 seconds
|
||||||
|
- Accessibility: WCAG 2.1 AA compliance
|
||||||
|
- Compatibility: Chrome, Firefox, Safari, Edge (latest 2 versions)
|
||||||
|
- SEO: Basic SEO metadata
|
||||||
|
- Offline: Basic offline support (cache API responses)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Architecture Overview
|
||||||
|
```
|
||||||
|
german-app-frontend/
|
||||||
|
├── public/ # Static files
|
||||||
|
│ └── audio/ # Audio files (served from backend)
|
||||||
|
├── src/
|
||||||
|
│ ├── components/ # Reusable UI components
|
||||||
|
│ │ ├── Dashboard/ # Progress bar, next lesson button
|
||||||
|
│ │ ├── Lesson/ # Vocabulary, Grammar, Story, Quiz tabs
|
||||||
|
│ │ ├── Quiz/ # Question type components
|
||||||
|
│ │ ├── Story/ # Story segment components
|
||||||
|
│ │ ├── Shared/ # Reusable UI elements
|
||||||
|
│ │ └── Layout/ # Header, Footer, Navigation
|
||||||
|
│ │
|
||||||
|
│ ├── pages/ # Page components
|
||||||
|
│ │ ├── DashboardPage.tsx
|
||||||
|
│ │ ├── LessonPage.tsx
|
||||||
|
│ │ ├── QuizPage.tsx
|
||||||
|
│ │ ├── StoryPage.tsx
|
||||||
|
│ │ ├── PracticePage.tsx
|
||||||
|
│ │ ├── ProfilePage.tsx
|
||||||
|
│ │ ├── LoginPage.tsx
|
||||||
|
│ │ └── RegisterPage.tsx
|
||||||
|
│ │
|
||||||
|
│ ├── hooks/ # Custom React hooks
|
||||||
|
│ │ ├── useApi.ts # API client hook
|
||||||
|
│ │ ├── useAuth.ts # Authentication hook
|
||||||
|
│ │ ├── useAudio.ts # Audio playback hook
|
||||||
|
│ │ ├── useRecorder.ts # Audio recording hook
|
||||||
|
│ │ └── useLesson.ts # Lesson data hook
|
||||||
|
│ │
|
||||||
|
│ ├── services/ # API and business logic services
|
||||||
|
│ │ ├── api.ts # Base API client
|
||||||
|
│ │ ├── authService.ts # Authentication service
|
||||||
|
│ │ ├── lessonService.ts # Lesson service
|
||||||
|
│ │ ├── quizService.ts # Quiz service
|
||||||
|
│ │ ├── speechService.ts # Speech recognition service
|
||||||
|
│ │ └── ttsService.ts # TTS service
|
||||||
|
│ │
|
||||||
|
│ ├── stores/ # State management
|
||||||
|
│ │ └── authStore.ts # Authentication state
|
||||||
|
│ │
|
||||||
|
│ ├── types/ # TypeScript type definitions
|
||||||
|
│ │ └── index.ts # API types, component props
|
||||||
|
│ │
|
||||||
|
│ ├── styles/ # Global styles
|
||||||
|
│ │ ├── tailwind.css # Tailwind CSS
|
||||||
|
│ │ └── global.css # Global styles
|
||||||
|
│ │
|
||||||
|
│ ├── utils/ # Utility functions
|
||||||
|
│ │ ├── constants.ts # Application constants
|
||||||
|
│ │ └── helpers.ts # Helper functions
|
||||||
|
│ │
|
||||||
|
│ ├── App.tsx # Main application component
|
||||||
|
│ └── main.tsx # Application entry point
|
||||||
|
│
|
||||||
|
├── package.json
|
||||||
|
├── vite.config.ts
|
||||||
|
└── tsconfig.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component Hierarchy
|
||||||
|
```
|
||||||
|
App
|
||||||
|
├── AuthContext
|
||||||
|
│ └── AuthProvider
|
||||||
|
├── Router
|
||||||
|
│ ├── PublicRoute
|
||||||
|
│ │ ├── LoginPage
|
||||||
|
│ │ ├── RegisterPage
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── PrivateRoute
|
||||||
|
│ ├── DashboardPage
|
||||||
|
│ ├── LessonPage
|
||||||
|
│ ├── QuizPage
|
||||||
|
│ ├── StoryPage
|
||||||
|
│ ├── PracticePage
|
||||||
|
│ └── ProfilePage
|
||||||
|
└── Layout
|
||||||
|
├── Header
|
||||||
|
└── Footer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
1. User navigates to a page
|
||||||
|
2. Page component uses custom hooks to fetch data
|
||||||
|
3. Hooks call services which use API client
|
||||||
|
4. API client makes HTTP requests to backend
|
||||||
|
5. Backend returns data
|
||||||
|
6. Hooks transform and provide data to components
|
||||||
|
7. Components render UI with data
|
||||||
|
8. User interactions trigger service calls
|
||||||
|
9. Services update backend via API
|
||||||
|
10. UI updates to reflect changes
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Project Setup (2-4 hours)
|
||||||
|
- [ ] Initialize Vite + React + TypeScript project
|
||||||
|
- [ ] Install dependencies (React Router, Tailwind CSS, Axios, etc.)
|
||||||
|
- [ ] Configure Vite for development and production
|
||||||
|
- [ ] Set up TypeScript configuration
|
||||||
|
- [ ] Configure Tailwind CSS
|
||||||
|
- [ ] Set up folder structure
|
||||||
|
- [ ] Configure environment variables
|
||||||
|
- [ ] Set up base HTML template
|
||||||
|
|
||||||
|
### Phase 2: Core Infrastructure (2-3 hours)
|
||||||
|
- [ ] Create API client with Axios
|
||||||
|
- [ ] Set up error handling and interceptors
|
||||||
|
- [ ] Create authentication context
|
||||||
|
- [ ] Implement protected route wrapper
|
||||||
|
- [ ] Set up state management (Zustand or Redux)
|
||||||
|
- [ ] Create type definitions for API responses
|
||||||
|
- [ ] Configure routing with React Router
|
||||||
|
|
||||||
|
### Phase 3: Shared Components (2-3 hours)
|
||||||
|
- [ ] Create Layout components (Header, Footer)
|
||||||
|
- [ ] Create Button, Input, Card components
|
||||||
|
- [ ] Create LoadingSpinner, ErrorMessage components
|
||||||
|
- [ ] Create AudioPlayer component
|
||||||
|
- [ ] Create Recorder component
|
||||||
|
- [ ] Create Modal component
|
||||||
|
- [ ] Create Notification system
|
||||||
|
|
||||||
|
### Phase 4: Authentication Pages (2 hours)
|
||||||
|
- [ ] Create LoginPage
|
||||||
|
- [ ] Create RegisterPage
|
||||||
|
- [ ] Create ProfilePage
|
||||||
|
- [ ] Implement form validation
|
||||||
|
- [ ] Integrate with AuthService
|
||||||
|
- [ ] Handle authentication state
|
||||||
|
|
||||||
|
### Phase 5: Dashboard Page (2 hours)
|
||||||
|
- [ ] Create DashboardPage
|
||||||
|
- [ ] Create ProgressBar component
|
||||||
|
- [ ] Create NextLessonButton component
|
||||||
|
- [ ] Create StoryProgress component
|
||||||
|
- [ ] Create Gamification components (PointsDisplay, StreakDisplay, BadgeList)
|
||||||
|
- [ ] Integrate with data hooks
|
||||||
|
|
||||||
|
### Phase 6: Lesson Pages (3-4 hours)
|
||||||
|
- [ ] Create LessonPage with tab navigation
|
||||||
|
- [ ] Create VocabularyTab component
|
||||||
|
- [ ] Create GrammarTab component
|
||||||
|
- [ ] Create StoryTab component
|
||||||
|
- [ ] Create ReadingTab component
|
||||||
|
- [ ] Create ListeningExercise component
|
||||||
|
- [ ] Create SpeakingExercise component
|
||||||
|
- [ ] Create WritingExercise component
|
||||||
|
- [ ] Create QuizTab component
|
||||||
|
- [ ] Integrate AudioPlayer and Recorder
|
||||||
|
|
||||||
|
### Phase 7: Quiz Pages (2 hours)
|
||||||
|
- [ ] Create QuizPage
|
||||||
|
- [ ] Create McqQuestion component
|
||||||
|
- [ ] Create FillInBlank component
|
||||||
|
- [ ] Create ListeningQuestion component
|
||||||
|
- [ ] Create MatchingQuestion component
|
||||||
|
- [ ] Create QuizResults component
|
||||||
|
- [ ] Implement quiz submission
|
||||||
|
- [ ] Display results with feedback
|
||||||
|
|
||||||
|
### Phase 8: Story Pages (2 hours)
|
||||||
|
- [ ] Create StoryPage
|
||||||
|
- [ ] Create StorySegment component
|
||||||
|
- [ ] Create StoryPlayer component
|
||||||
|
- [ ] Implement word click-to-translate
|
||||||
|
- [ ] Add story navigation
|
||||||
|
- [ ] Display story progress
|
||||||
|
|
||||||
|
### Phase 9: Practice Pages (2 hours)
|
||||||
|
- [ ] Create PracticePage
|
||||||
|
- [ ] Create SpeakingPractice component
|
||||||
|
- [ ] Create WritingPractice component
|
||||||
|
- [ ] Integrate speech recognition
|
||||||
|
- [ ] Integrate writing feedback
|
||||||
|
- [ ] Display practice history
|
||||||
|
|
||||||
|
### Phase 10: Polish & Testing (2 hours)
|
||||||
|
- [ ] Add loading states
|
||||||
|
- [ ] Add error boundaries
|
||||||
|
- [ ] Implement form validation
|
||||||
|
- [ ] Add responsive design tweaks
|
||||||
|
- [ ] Test on mobile devices
|
||||||
|
- [ ] Performance optimization
|
||||||
|
- [ ] Accessibility audit
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Project Setup | - | ⏳ |
|
||||||
|
| Core Infrastructure | - | ⏳ |
|
||||||
|
| Shared Components | - | ⏳ |
|
||||||
|
| Authentication Pages | - | ⏳ |
|
||||||
|
| Dashboard Page | - | ⏳ |
|
||||||
|
| Lesson Pages | - | ⏳ |
|
||||||
|
| Quiz Pages | - | ⏳ |
|
||||||
|
| Story Pages | - | ⏳ |
|
||||||
|
| Practice Pages | - | ⏳ |
|
||||||
|
| Polish & Testing | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Project Setup
|
||||||
|
- [ ] Initialize Vite project
|
||||||
|
- [ ] Install React and React DOM
|
||||||
|
- [ ] Install TypeScript
|
||||||
|
- [ ] Install React Router
|
||||||
|
- [ ] Install Tailwind CSS
|
||||||
|
- [ ] Install Axios
|
||||||
|
- [ ] Install Zustand (or Redux Toolkit)
|
||||||
|
- [ ] Install @testing-library/react
|
||||||
|
- [ ] Install other dependencies
|
||||||
|
- [ ] Configure Vite
|
||||||
|
- [ ] Configure TypeScript
|
||||||
|
- [ ] Configure Tailwind
|
||||||
|
- [ ] Set up folder structure
|
||||||
|
- [ ] Create base files
|
||||||
|
|
||||||
|
### Core Infrastructure
|
||||||
|
- [ ] Create src/services/api.ts
|
||||||
|
- [ ] Create src/contexts/AuthContext.tsx
|
||||||
|
- [ ] Create src/components/Layout/PrivateRoute.tsx
|
||||||
|
- [ ] Create src/components/Layout/PublicRoute.tsx
|
||||||
|
- [ ] Create src/types/index.ts
|
||||||
|
- [ ] Set up React Router in main.tsx
|
||||||
|
- [ ] Configure Axios interceptors
|
||||||
|
|
||||||
|
### Shared Components
|
||||||
|
- [ ] Create src/components/Layout/Header.tsx
|
||||||
|
- [ ] Create src/components/Layout/Footer.tsx
|
||||||
|
- [ ] Create src/components/Shared/Button.tsx
|
||||||
|
- [ ] Create src/components/Shared/Input.tsx
|
||||||
|
- [ ] Create src/components/Shared/Card.tsx
|
||||||
|
- [ ] Create src/components/Shared/LoadingSpinner.tsx
|
||||||
|
- [ ] Create src/components/Shared/ErrorMessage.tsx
|
||||||
|
- [ ] Create src/components/Shared/AudioPlayer.tsx
|
||||||
|
- [ ] Create src/components/Shared/Recorder.tsx
|
||||||
|
- [ ] Create src/components/Shared/Modal.tsx
|
||||||
|
- [ ] Create src/components/Shared/Notification.tsx
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
- [ ] Create src/pages/LoginPage.tsx
|
||||||
|
- [ ] Create src/pages/RegisterPage.tsx
|
||||||
|
- [ ] Create src/pages/ProfilePage.tsx
|
||||||
|
- [ ] Create src/hooks/useAuth.ts
|
||||||
|
- [ ] Create src/services/authService.ts
|
||||||
|
- [ ] Implement form validation
|
||||||
|
- [ ] Integrate with AuthContext
|
||||||
|
|
||||||
|
### Dashboard
|
||||||
|
- [ ] Create src/pages/DashboardPage.tsx
|
||||||
|
- [ ] Create src/components/Dashboard/ProgressBar.tsx
|
||||||
|
- [ ] Create src/components/Dashboard/NextLessonButton.tsx
|
||||||
|
- [ ] Create src/components/Dashboard/StoryProgress.tsx
|
||||||
|
- [ ] Create src/components/Gamification/PointsDisplay.tsx
|
||||||
|
- [ ] Create src/components/Gamification/StreakDisplay.tsx
|
||||||
|
- [ ] Create src/components/Gamification/BadgeDisplay.tsx
|
||||||
|
- [ ] Create src/hooks/useDashboard.ts
|
||||||
|
|
||||||
|
### Lesson Components
|
||||||
|
- [ ] Create src/pages/LessonPage.tsx
|
||||||
|
- [ ] Create src/components/Lesson/VocabularyTab.tsx
|
||||||
|
- [ ] Create src/components/Lesson/GrammarTab.tsx
|
||||||
|
- [ ] Create src/components/Lesson/StoryTab.tsx
|
||||||
|
- [ ] Create src/components/Lesson/ReadingTab.tsx
|
||||||
|
- [ ] Create src/components/Lesson/ListeningExercise.tsx
|
||||||
|
- [ ] Create src/components/Lesson/SpeakingExercise.tsx
|
||||||
|
- [ ] Create src/components/Lesson/WritingExercise.tsx
|
||||||
|
- [ ] Create src/components/Lesson/QuizTab.tsx
|
||||||
|
- [ ] Create src/hooks/useLesson.ts
|
||||||
|
|
||||||
|
### Quiz Components
|
||||||
|
- [ ] Create src/pages/QuizPage.tsx
|
||||||
|
- [ ] Create src/components/Quiz/McqQuestion.tsx
|
||||||
|
- [ ] Create src/components/Quiz/FillInBlank.tsx
|
||||||
|
- [ ] Create src/components/Quiz/ListeningQuestion.tsx
|
||||||
|
- [ ] Create src/components/Quiz/MatchingQuestion.tsx
|
||||||
|
- [ ] Create src/components/Quiz/QuizResults.tsx
|
||||||
|
- [ ] Create src/hooks/useQuiz.ts
|
||||||
|
- [ ] Create src/services/quizService.ts
|
||||||
|
|
||||||
|
### Story Components
|
||||||
|
- [ ] Create src/pages/StoryPage.tsx
|
||||||
|
- [ ] Create src/components/Story/StorySegment.tsx
|
||||||
|
- [ ] Create src/components/Story/StoryPlayer.tsx
|
||||||
|
- [ ] Create src/hooks/useStory.ts
|
||||||
|
- [ ] Create src/services/storyService.ts
|
||||||
|
- [ ] Implement word translation on click
|
||||||
|
|
||||||
|
### Practice Components
|
||||||
|
- [ ] Create src/pages/PracticePage.tsx
|
||||||
|
- [ ] Create src/components/Practice/SpeakingPractice.tsx
|
||||||
|
- [ ] Create src/components/Practice/WritingPractice.tsx
|
||||||
|
- [ ] Create src/hooks/usePractice.ts
|
||||||
|
- [ ] Create src/services/speechService.ts
|
||||||
|
- [ ] Create src/services/ttsService.ts
|
||||||
|
|
||||||
|
### Polish & Testing
|
||||||
|
- [ ] Add loading states to all components
|
||||||
|
- [ ] Add error boundaries
|
||||||
|
- [ ] Implement form validation
|
||||||
|
- [ ] Add responsive design
|
||||||
|
- [ ] Test on mobile devices
|
||||||
|
- [ ] Optimize bundle size
|
||||||
|
- [ ] Run accessibility audit
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Backend must be ready
|
||||||
|
- [User Authentication](user-authentication.md) - Auth flow must be implemented
|
||||||
|
- [Lesson Management](lesson-management.md) - Lesson data must be available
|
||||||
|
- [Vocabulary System](vocabulary-system.md) - Vocabulary data must be available
|
||||||
|
- [Quiz System](quiz-system.md) - Quiz data must be available
|
||||||
|
- [Story Integration](story-integration.md) - Story data must be available
|
||||||
|
- [AI Services](ai-services.md) - AI services must be available
|
||||||
|
- [Gamification](gamification.md) - Gamification data must be available
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Node.js 18+
|
||||||
|
- npm or yarn
|
||||||
|
- Vite
|
||||||
|
- React 19
|
||||||
|
- TypeScript
|
||||||
|
- Tailwind CSS
|
||||||
|
- React Router
|
||||||
|
- Axios
|
||||||
|
- Zustand or Redux
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Backend API endpoints must be implemented
|
||||||
|
- [ ] AI services must be configured
|
||||||
|
- [ ] Database must be set up
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Frontend-Specific Criteria
|
||||||
|
- [ ] React application builds successfully
|
||||||
|
- [ ] All pages render without errors
|
||||||
|
- [ ] All components render without errors
|
||||||
|
- [ ] All hooks work correctly
|
||||||
|
- [ ] All services work correctly
|
||||||
|
- [ ] API calls return expected data
|
||||||
|
- [ ] Authentication flow works end-to-end
|
||||||
|
- [ ] Audio playback works on all supported browsers
|
||||||
|
- [ ] Audio recording works on all supported browsers
|
||||||
|
- [ ] Responsive design works on mobile, tablet, and desktop
|
||||||
|
- [ ] Form validation works correctly
|
||||||
|
- [ ] Error handling displays user-friendly messages
|
||||||
|
- [ ] Loading states are displayed appropriately
|
||||||
|
- [ ] Accessibility meets WCAG 2.1 AA standards
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Frontend-Specific Tests
|
||||||
|
|
||||||
|
#### Component Tests
|
||||||
|
- [ ] All components render without errors
|
||||||
|
- [ ] All components render with required props
|
||||||
|
- [ ] All components render with optional props
|
||||||
|
- [ ] All components handle user interactions correctly
|
||||||
|
- [ ] All components display loading states
|
||||||
|
- [ ] All components display error states
|
||||||
|
- [ ] All components are accessible (keyboard, screen reader)
|
||||||
|
- [ ] All components are responsive
|
||||||
|
|
||||||
|
#### Page Tests
|
||||||
|
- [ ] Dashboard page loads and displays data
|
||||||
|
- [ ] Lesson page loads and displays lesson content
|
||||||
|
- [ ] Lesson page tabs work correctly
|
||||||
|
- [ ] Quiz page loads and displays questions
|
||||||
|
- [ ] Quiz page submission works
|
||||||
|
- [ ] Story page loads and displays segments
|
||||||
|
- [ ] Story page audio works
|
||||||
|
- [ ] Practice page loads and displays exercises
|
||||||
|
- [ ] Practice page speech recognition works
|
||||||
|
- [ ] Practice page writing feedback works
|
||||||
|
- [ ] Login page loads and handles submission
|
||||||
|
- [ ] Register page loads and handles submission
|
||||||
|
- [ ] Profile page loads and displays user data
|
||||||
|
|
||||||
|
#### Service Tests
|
||||||
|
- [ ] API client makes correct requests
|
||||||
|
- [ ] API client handles errors correctly
|
||||||
|
- [ ] API client includes auth headers
|
||||||
|
- [ ] Auth service handles login/logout
|
||||||
|
- [ ] Lesson service returns correct data
|
||||||
|
- [ ] Quiz service handles submission
|
||||||
|
- [ ] Speech service handles recording/transcription
|
||||||
|
- [ ] TTS service handles audio generation
|
||||||
|
|
||||||
|
#### Integration Tests
|
||||||
|
- [ ] Auth context provides user state
|
||||||
|
- [ ] Protected routes redirect correctly
|
||||||
|
- [ ] Public routes are accessible
|
||||||
|
- [ ] AudioPlayer component plays audio
|
||||||
|
- [ ] Recorder component captures audio
|
||||||
|
- [ ] Modal component opens/closes
|
||||||
|
- [ ] Notification system displays messages
|
||||||
|
|
||||||
|
#### E2E Tests (Critical Journeys)
|
||||||
|
- [ ] User registration → login → view dashboard
|
||||||
|
- [ ] User navigation to lesson → complete activities → take quiz
|
||||||
|
- [ ] User navigation to story → listen to audio
|
||||||
|
- [ ] User completes lesson → quiz → progress updated
|
||||||
|
- [ ] User earns badge → badge displayed on profile
|
||||||
|
|
||||||
|
#### Browser Compatibility Tests
|
||||||
|
- [ ] All functionality works on Chrome (latest 2 versions)
|
||||||
|
- [ ] All functionality works on Firefox (latest 2 versions)
|
||||||
|
- [ ] All functionality works on Safari (latest 2 versions)
|
||||||
|
- [ ] All functionality works on Edge (latest 2 versions)
|
||||||
|
- [ ] Audio recording works on mobile Chrome
|
||||||
|
- [ ] Audio recording works on mobile Safari
|
||||||
|
- [ ] Responsive design works on all screen sizes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Vite over Create React App | Faster, more modern, better DX |
|
||||||
|
| May 31, 2025 | React 19 | Latest stable version |
|
||||||
|
| May 31, 2025 | TypeScript | Type safety, better developer experience |
|
||||||
|
| May 31, 2025 | Tailwind CSS | Rapid styling, consistent design |
|
||||||
|
| May 31, 2025 | Zustand for state | Simpler than Redux, good TypeScript support |
|
||||||
|
| May 31, 2025 | Axios for HTTP | Better error handling than fetch |
|
||||||
|
| May 31, 2025 | Mobile-first | Most users will be on mobile |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Use functional components with hooks
|
||||||
|
- Use TypeScript interfaces for all props
|
||||||
|
- Use async/await for API calls
|
||||||
|
- Handle loading and error states gracefully
|
||||||
|
- Use environment variables for API base URL
|
||||||
|
- Audio files served from backend /public/audio/
|
||||||
|
- Consider lazy loading for large components
|
||||||
|
|
||||||
|
### Component Library Considerations
|
||||||
|
For MVP, use custom components. Consider these libraries for future:
|
||||||
|
- **UI Components**: shadcn/ui, Radix UI, or Material UI
|
||||||
|
- **Forms**: React Hook Form + Zod
|
||||||
|
- **Icons**: Lucide React or Heroicons
|
||||||
|
- **Animations**: Framer Motion
|
||||||
|
- **Charts**: Recharts or Chart.js
|
||||||
|
|
||||||
|
### Audio Handling
|
||||||
|
- Use HTML5 Audio element for playback
|
||||||
|
- Use MediaRecorder API for recording
|
||||||
|
- Handle microphone permission errors
|
||||||
|
- Support Web Audio API for advanced features
|
||||||
|
- Consider audio compression for upload
|
||||||
|
|
||||||
|
### Performance Optimization
|
||||||
|
- Code splitting with React.lazy
|
||||||
|
- Image optimization
|
||||||
|
- Bundle analysis with rollup-plugin-visualizer
|
||||||
|
- Service worker for caching (workbox)
|
||||||
|
- Preload important resources
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ MediaRecorder API may not work on some mobile browsers
|
||||||
|
- ⚠️ Audio playback may be blocked without user interaction
|
||||||
|
- ⚠️ Safari has different audio format support
|
||||||
|
- ⚠️ Mobile keyboards may cover input fields
|
||||||
|
- ⚠️ Touch targets must be large enough for mobile
|
||||||
|
- ⚠️ CORS issues with audio files from different domains
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Frontend Structure](../architecture/frontend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Feature: [Infrastructure Setup](infrastructure-setup.md)
|
||||||
|
- Feature: [User Authentication](user-authentication.md)
|
||||||
|
- Feature: [Lesson Management](lesson-management.md)
|
||||||
|
- Feature: [Vocabulary System](vocabulary-system.md)
|
||||||
|
- Feature: [Quiz System](quiz-system.md)
|
||||||
|
- Feature: [Story Integration](story-integration.md)
|
||||||
|
- Feature: [AI Services](ai-services.md)
|
||||||
|
- Feature: [Gamification](gamification.md)
|
||||||
|
- Reference: [Vite Docs](https://vitejs.dev/)
|
||||||
|
- Reference: [React Docs](https://react.dev/)
|
||||||
|
- Reference: [TypeScript Docs](https://www.typescriptlang.org/docs/)
|
||||||
|
- Reference: [Tailwind CSS Docs](https://tailwindcss.com/docs)
|
||||||
|
- Reference: [React Router Docs](https://reactrouter.com/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
416
docs/features/gamification.md
Normal file
416
docs/features/gamification.md
Normal file
|
|
@ -0,0 +1,416 @@
|
||||||
|
# Feature: Gamification System
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: Medium
|
||||||
|
> **Complexity**: Medium
|
||||||
|
> **Estimate**: 6-8 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, User Authentication, Lesson Management, Quiz System
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement gamification features (points, badges, streaks) to motivate users and provide a sense of achievement as they progress through the German learning journey.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a learner, I want to earn points, badges, and maintain streaks for my learning activities so that I stay motivated and can see my progress over time.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Users earn points for completing lessons and passing quizzes
|
||||||
|
- [ ] Users earn badges for specific achievements
|
||||||
|
- [ ] Daily streaks are tracked and displayed
|
||||||
|
- [ ] Users can view their points, badges, and streak on dashboard
|
||||||
|
- [ ] Leaderboard shows top users (optional)
|
||||||
|
- [ ] Achievement notifications are displayed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | Earn points for completing lessons | High |
|
||||||
|
| FR-002 | Earn points for passing quizzes | High |
|
||||||
|
| FR-003 | Define and award badges for achievements | High |
|
||||||
|
| FR-004 | Track daily learning streaks | High |
|
||||||
|
| FR-005 | Display points, badges, streak on dashboard | High |
|
||||||
|
| FR-006 | Show badge details and unlock criteria | Medium |
|
||||||
|
| FR-007 | Implement leaderboard (optional) | Low |
|
||||||
|
| FR-008 | Send achievement notifications | Low |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Gamification updates < 100ms
|
||||||
|
- Scalability: System should handle thousands of users
|
||||||
|
- Security: Prevent points/badges exploitation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: GamificationController, GamificationService, PointsService, BadgeService, StreakService
|
||||||
|
- **Database**: Badges, UserBadges tables (from schema), Users table (points and streak fields)
|
||||||
|
- **Models**: Badge, UserBadge, PointsTransaction, Achievement
|
||||||
|
- **Frontend**: Dashboard components, BadgeDisplay, PointsDisplay, StreakDisplay
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
1. User completes a lesson or passes a quiz
|
||||||
|
2. Backend calculates points earned
|
||||||
|
3. Backend updates User.TotalPoints
|
||||||
|
4. Backend checks if any badges are earned
|
||||||
|
5. If badge earned, create UserBadge record
|
||||||
|
6. Backend updates daily streak if applicable
|
||||||
|
7. Frontend displays updated gamification data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Points System
|
||||||
|
| Action | Points | Notes |
|
||||||
|
|--------|--------|-------|
|
||||||
|
| Complete Lesson | 10 | Awarded once per lesson |
|
||||||
|
| Pass Quiz (first try) | 20 | Bonus for first-time pass |
|
||||||
|
| Pass Quiz (subsequent) | 10 | Still earns points |
|
||||||
|
| Perfect Quiz Score | +5 | Bonus for 100% |
|
||||||
|
| Daily Login | 5 | Encourages daily use |
|
||||||
|
|
||||||
|
### Badge System
|
||||||
|
| Badge Name | Criteria | Description |
|
||||||
|
|------------|----------|-------------|
|
||||||
|
| First Lesson | Complete 1 lesson | Getting Started |
|
||||||
|
| A1 Complete | Complete all A1 lessons | A1 Master |
|
||||||
|
| Perfect Score | Pass 5 quizzes with 100% | Perfect Student |
|
||||||
|
| Streak 7 | 7-day learning streak | Weekly Warrior |
|
||||||
|
| Streak 30 | 30-day learning streak | Monthly Marvel |
|
||||||
|
| Early Bird | Complete lesson before 9 AM | Morning Learner |
|
||||||
|
| Night Owl | Complete lesson after 9 PM | Late Night Learner |
|
||||||
|
| Vocabulary Master | Learn 100 words | Word Champion |
|
||||||
|
| Grammar Guru | Pass 10 grammar quizzes | Grammar Expert |
|
||||||
|
|
||||||
|
### Streak System
|
||||||
|
- Streak increments by 1 for each day with at least one completed activity
|
||||||
|
- Streak resets if user has no activity for 24 hours
|
||||||
|
- Last activity timestamp stored in User table
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
| Endpoint | Method | Description | Auth Required |
|
||||||
|
|----------|--------|-------------|----------------|
|
||||||
|
| `/api/gamification/me` | GET | Get current user's gamification data | Yes |
|
||||||
|
| `/api/gamification/points` | GET | Get user's points history | Yes |
|
||||||
|
| `/api/gamification/badges` | GET | List all badges | Yes |
|
||||||
|
| `/api/gamification/badges/earned` | GET | List user's earned badges | Yes |
|
||||||
|
| `/api/gamification/badges/{id}` | GET | Get badge details | Yes |
|
||||||
|
| `/api/gamification/leaderboard` | GET | Get top users by points | Yes |
|
||||||
|
| `/api/gamification/streak` | GET | Get streak information | Yes |
|
||||||
|
|
||||||
|
### Database Schema (from application-plan.md)
|
||||||
|
```sql
|
||||||
|
-- Badges table
|
||||||
|
CREATE TABLE Badges (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
Name VARCHAR(50) NOT NULL,
|
||||||
|
Description TEXT,
|
||||||
|
ImageUrl VARCHAR(255),
|
||||||
|
CriteriaType VARCHAR(50) NOT NULL, -- e.g., 'lessons_completed', 'streak_days'
|
||||||
|
CriteriaValue INT NOT NULL, -- e.g., 10 for 10 lessons completed
|
||||||
|
PointsReward INT DEFAULT 0,
|
||||||
|
UNIQUE(Name)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- User Badges table
|
||||||
|
CREATE TABLE UserBadges (
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
BadgeId INT REFERENCES Badges(Id) ON DELETE CASCADE,
|
||||||
|
EarnedDate TIMESTAMP DEFAULT NOW(),
|
||||||
|
PRIMARY KEY (UserId, BadgeId)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Users table (existing fields)
|
||||||
|
ALTER TABLE Users ADD COLUMN TotalPoints INT DEFAULT 0;
|
||||||
|
ALTER TABLE Users ADD COLUMN Streak INT DEFAULT 0;
|
||||||
|
ALTER TABLE Users ADD COLUMN LastActivityDate TIMESTAMP;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Database & Models (2 hours)
|
||||||
|
- [ ] Update Users table with gamification fields
|
||||||
|
- [ ] Create Badge entity
|
||||||
|
- [ ] Create UserBadge entity
|
||||||
|
- [ ] Create PointsTransaction entity (optional for history)
|
||||||
|
- [ ] Create DTOs for gamification data
|
||||||
|
- [ ] Create migrations
|
||||||
|
- [ ] Seed initial badges
|
||||||
|
|
||||||
|
### Phase 2: Points Service (1-2 hours)
|
||||||
|
- [ ] Create PointsService
|
||||||
|
- [ ] Implement points calculation logic
|
||||||
|
- [ ] Create points awarding mechanism
|
||||||
|
- [ ] Implement points history tracking
|
||||||
|
- [ ] Create PointsTransaction repository
|
||||||
|
|
||||||
|
### Phase 3: Badge Service (2 hours)
|
||||||
|
- [ ] Create BadgeService
|
||||||
|
- [ ] Implement badge criteria checking
|
||||||
|
- [ ] Create badge awarding mechanism
|
||||||
|
- [ ] Implement badge checking on user actions
|
||||||
|
- [ ] Create badge details endpoint
|
||||||
|
|
||||||
|
### Phase 4: Streak Service (1-2 hours)
|
||||||
|
- [ ] Create StreakService
|
||||||
|
- [ ] Implement streak calculation logic
|
||||||
|
- [ ] Create streak update mechanism
|
||||||
|
- [ ] Handle streak reset logic
|
||||||
|
- [ ] Create streak endpoint
|
||||||
|
|
||||||
|
### Phase 5: Gamification Controller (1 hour)
|
||||||
|
- [ ] Create GamificationController
|
||||||
|
- [ ] Implement all endpoints
|
||||||
|
- [ ] Add authorization
|
||||||
|
- [ ] Add validation
|
||||||
|
- [ ] Write tests
|
||||||
|
|
||||||
|
### Phase 6: Frontend Integration (2 hours)
|
||||||
|
- [ ] Create Dashboard gamification section
|
||||||
|
- [ ] Create BadgeDisplay component
|
||||||
|
- [ ] Create PointsDisplay component
|
||||||
|
- [ ] Create StreakDisplay component
|
||||||
|
- [ ] Create Leaderboard component (optional)
|
||||||
|
- [ ] Add achievement notifications
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Database & Models | - | ⏳ |
|
||||||
|
| Points Service | - | ⏳ |
|
||||||
|
| Badge Service | - | ⏳ |
|
||||||
|
| Streak Service | - | ⏳ |
|
||||||
|
| Controller | - | ⏳ |
|
||||||
|
| Frontend Integration | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Update Domain/Entities/User.cs with gamification fields
|
||||||
|
- [ ] Create Domain/Entities/Badge.cs
|
||||||
|
- [ ] Create Domain/Entities/UserBadge.cs
|
||||||
|
- [ ] Create Application/DTOs/GamificationDto.cs
|
||||||
|
- [ ] Create Application/DTOs/BadgeDto.cs
|
||||||
|
- [ ] Create Application/DTOs/UserBadgeDto.cs
|
||||||
|
- [ ] Create Domain/Interfaces/IBadgeRepository.cs
|
||||||
|
- [ ] Create Domain/Interfaces/IUserBadgeRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/BadgeRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/UserBadgeRepository.cs
|
||||||
|
- [ ] Create Application/Services/PointsService.cs
|
||||||
|
- [ ] Create Application/Services/BadgeService.cs
|
||||||
|
- [ ] Create Application/Services/StreakService.cs
|
||||||
|
- [ ] Create Application/Services/GamificationService.cs
|
||||||
|
- [ ] Create Presentation/Controllers/GamificationController.cs
|
||||||
|
- [ ] Register services in Program.cs
|
||||||
|
- [ ] Write unit tests
|
||||||
|
- [ ] Write integration tests
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Create migration for gamification fields in Users
|
||||||
|
- [ ] Create migration for Badges table
|
||||||
|
- [ ] Create migration for UserBadges table
|
||||||
|
- [ ] Seed initial badges
|
||||||
|
- [ ] Apply migrations
|
||||||
|
|
||||||
|
### Integration
|
||||||
|
- [ ] Integrate PointsService with LessonService
|
||||||
|
- [ ] Integrate PointsService with QuizService
|
||||||
|
- [ ] Integrate BadgeService with user actions
|
||||||
|
- [ ] Integrate StreakService with user activity
|
||||||
|
- [ ] Add gamification updates to relevant endpoints
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] Update DashboardPage with gamification section
|
||||||
|
- [ ] Create components/Gamification/PointsDisplay.tsx
|
||||||
|
- [ ] Create components/Gamification/StreakDisplay.tsx
|
||||||
|
- [ ] Create components/Gamification/BadgeDisplay.tsx
|
||||||
|
- [ ] Create components/Gamification/BadgeList.tsx
|
||||||
|
- [ ] Create components/Gamification/Leaderboard.tsx (optional)
|
||||||
|
- [ ] Create hooks/useGamification.ts
|
||||||
|
- [ ] Add achievement notification system
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required
|
||||||
|
- [User Authentication](user-authentication.md) - Required (for user-specific data)
|
||||||
|
- [Lesson Management](lesson-management.md) - Required (points for lessons)
|
||||||
|
- [Quiz System](quiz-system.md) - Required (points for quizzes)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Entity Framework Core
|
||||||
|
- AutoMapper (optional)
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete
|
||||||
|
- [ ] User Authentication must be complete
|
||||||
|
- [ ] Lesson Management must be complete
|
||||||
|
- [ ] Quiz System must be complete
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Gamification-Specific Criteria
|
||||||
|
- [ ] Points are earned for all defined actions
|
||||||
|
- [ ] Points are displayed correctly on dashboard
|
||||||
|
- [ ] All badges are defined and seeded
|
||||||
|
- [ ] Badges are awarded automatically when criteria met
|
||||||
|
- [ ] Earned badges are displayed on user profile
|
||||||
|
- [ ] Daily streaks are tracked correctly
|
||||||
|
- [ ] Streak is displayed on dashboard
|
||||||
|
- [ ] Leaderboard (if implemented) shows correct data
|
||||||
|
- [ ] Achievement notifications are displayed
|
||||||
|
- [ ] Points and badges cannot be manipulated client-side
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Gamification-Specific Tests
|
||||||
|
|
||||||
|
#### Backend Tests
|
||||||
|
- [ ] Points awarded for lesson completion → correct amount
|
||||||
|
- [ ] Points awarded for quiz pass (first try) → correct amount
|
||||||
|
- [ ] Points awarded for quiz pass (subsequent) → correct amount
|
||||||
|
- [ ] Points awarded for perfect quiz → correct amount + bonus
|
||||||
|
- [ ] Points NOT awarded for quiz fail → no change
|
||||||
|
- [ ] Badge awarded when criteria met → badge created
|
||||||
|
- [ ] Badge NOT awarded when criteria not met → no change
|
||||||
|
- [ ] Multiple badges can be earned simultaneously → all awarded
|
||||||
|
- [ ] Streak increments on daily activity → +1
|
||||||
|
- [ ] Streak resets after inactivity → 0
|
||||||
|
- [ ] Streak maintains across days → correct count
|
||||||
|
- [ ] Leaderboard returns top N users → correct ordering
|
||||||
|
|
||||||
|
#### Business Logic Tests
|
||||||
|
- [ ] Points calculation with various actions → correct total
|
||||||
|
- [ ] Badge criteria evaluation → correct determination
|
||||||
|
- [ ] Streak calculation across time zones → consistent
|
||||||
|
- [ ] Concurrent points awards → no race conditions
|
||||||
|
- [ ] Badge awarding is idempotent → only awarded once
|
||||||
|
|
||||||
|
#### Security Tests
|
||||||
|
- [ ] Points cannot be awarded client-side → server-only
|
||||||
|
- [ ] Badges cannot be awarded client-side → server-only
|
||||||
|
- [ ] Streak cannot be manipulated client-side → server-only
|
||||||
|
- [ ] Leaderboard doesn't expose sensitive data → verified
|
||||||
|
|
||||||
|
#### Frontend Tests
|
||||||
|
- [ ] Points display updates after earning → correct
|
||||||
|
- [ ] Badge display shows earned badges → correct
|
||||||
|
- [ ] Badge details modal shows correct info → verified
|
||||||
|
- [ ] Streak display updates daily → correct
|
||||||
|
- [ ] Achievement notification appears when earned → verified
|
||||||
|
- [ ] Leaderboard displays correctly → verified
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Points for lesson completion | Encourages progress through curriculum |
|
||||||
|
| May 31, 2025 | Badge system | Provides goals and achievements |
|
||||||
|
| May 31, 2025 | Daily streaks | Encourages consistent daily use |
|
||||||
|
| May 31, 2025 | Server-authoritative | Prevents client-side manipulation of points |
|
||||||
|
| May 31, 2025 | No negative points | Positive reinforcement only |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Points should be awarded server-side only, never client-side
|
||||||
|
- Badge criteria should be checked on relevant user actions
|
||||||
|
- Streak calculation: Compare LastActivityDate with previous day
|
||||||
|
- Consider time zones for daily streaks (use UTC for consistency)
|
||||||
|
- Badge images can be stored as URLs or base64 encoded
|
||||||
|
|
||||||
|
### Points Calculation Examples
|
||||||
|
```
|
||||||
|
Lesson Completion:
|
||||||
|
- Base: 10 points
|
||||||
|
- First-time: +10 = 20 points total (with Quiz bonus)
|
||||||
|
|
||||||
|
Quiz Pass:
|
||||||
|
- First try: 20 points
|
||||||
|
- Subsequent: 10 points
|
||||||
|
- Perfect score: +5 bonus
|
||||||
|
```
|
||||||
|
|
||||||
|
### Badge Criteria Types
|
||||||
|
- `lessons_completed`: Number of lessons completed
|
||||||
|
- `quizzes_passed`: Number of quizzes passed
|
||||||
|
- `streak_days`: Current streak in days
|
||||||
|
- `perfect_quizzes`: Number of perfect scores
|
||||||
|
- `vocabulary_learned`: Number of vocabulary words mastered
|
||||||
|
- `levels_completed`: Number of CEFR levels completed
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Points can get large - use INT or BIGINT
|
||||||
|
- ⚠️ Badge criteria may need adjustment based on testing
|
||||||
|
- ⚠️ Streak calculation must handle time zones correctly
|
||||||
|
- ⚠️ Users may try to game the system - validate all inputs
|
||||||
|
- ⚠️ Badge images may have copyright issues - use original or licensed images
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Feature: [User Authentication](user-authentication.md)
|
||||||
|
- Feature: [Lesson Management](lesson-management.md)
|
||||||
|
- Feature: [Quiz System](quiz-system.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
273
docs/features/infrastructure-setup.md
Normal file
273
docs/features/infrastructure-setup.md
Normal file
|
|
@ -0,0 +1,273 @@
|
||||||
|
# Feature: Infrastructure Setup
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: Medium
|
||||||
|
> **Estimate**: 10-14 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **Related Features**: All other features depend on this
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Establish the foundational infrastructure for the DeutschLernen application, including backend project, database, and core dependencies.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a developer, I want to have a working backend and database setup so that I can begin implementing application features.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] .NET 9.0 backend project is created and builds successfully
|
||||||
|
- [ ] PostgreSQL database is configured and accessible
|
||||||
|
- [ ] Docker setup is ready for deployment
|
||||||
|
- [ ] CI/CD pipeline is configured
|
||||||
|
- [ ] Development environment is reproducible
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | .NET 9.0 backend with ASP.NET Core Web API | High |
|
||||||
|
| FR-002 | PostgreSQL database with connection string configuration | High |
|
||||||
|
| FR-003 | Docker containers for backend and database | High |
|
||||||
|
| FR-004 | GitHub Actions CI/CD pipeline | Medium |
|
||||||
|
| FR-005 | Environment configuration (development, staging, production) | Medium |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Backend should start in < 5 seconds
|
||||||
|
- Security: Database credentials stored securely (not in code)
|
||||||
|
- Compatibility: Works on Linux, Windows, and macOS
|
||||||
|
- Scalability: Infrastructure should support horizontal scaling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: ASP.NET Core Web API project
|
||||||
|
- **Database**: PostgreSQL 15+
|
||||||
|
- **Infrastructure**: Docker, Docker Compose
|
||||||
|
- **CI/CD**: GitHub Actions
|
||||||
|
|
||||||
|
### Architecture Diagram
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ Infrastructure │
|
||||||
|
├─────────────────────────────────────────────────────────┤
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ Backend │ │ Database │ │ Frontend │ │
|
||||||
|
│ │ (.NET 9.0) │◄──►│ PostgreSQL │ │ (React) │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ ▲ ▲ ▲ │
|
||||||
|
│ │ │ │ │
|
||||||
|
│ ┌────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ │
|
||||||
|
│ │ Docker │ │ Docker │ │ Docker │ │
|
||||||
|
│ │ Container│ │ Container │ │ Container │ │
|
||||||
|
│ └──────────┘ └───────────┘ └───────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
1. Developer runs `docker-compose up`
|
||||||
|
2. PostgreSQL container starts with initialized database
|
||||||
|
3. Backend container starts and connects to database
|
||||||
|
4. Frontend container starts and connects to backend API
|
||||||
|
5. Application is accessible at `http://localhost:3000`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Backend Project Setup (2-4 hours)
|
||||||
|
- [ ] Create GermanApp .NET 9.0 Web API project
|
||||||
|
- [ ] Configure appsettings.json with multiple environments
|
||||||
|
- [ ] Set up Health Checks endpoint
|
||||||
|
- [ ] Configure CORS for frontend
|
||||||
|
- [ ] Set up OpenAPI/Swagger documentation
|
||||||
|
- [ ] Configure logging (Serilog or built-in)
|
||||||
|
- [ ] Create base response models and error handling middleware
|
||||||
|
|
||||||
|
### Phase 2: Database Setup (1-2 hours)
|
||||||
|
- [ ] Design and create initial database schema
|
||||||
|
- [ ] Configure Entity Framework Core with PostgreSQL
|
||||||
|
- [ ] Set up database migrations
|
||||||
|
- [ ] Create seed data scripts
|
||||||
|
- [ ] Configure connection strings for different environments
|
||||||
|
|
||||||
|
### Phase 3: Docker Configuration (2-4 hours)
|
||||||
|
- [ ] Create Dockerfile for backend
|
||||||
|
- [ ] Create Dockerfile for frontend
|
||||||
|
- [ ] Create docker-compose.yml with all services
|
||||||
|
- [ ] Configure Docker volumes for persistent data
|
||||||
|
- [ ] Set up environment variables in Docker
|
||||||
|
- [ ] Test Docker build and run
|
||||||
|
|
||||||
|
### Phase 4: CI/CD Pipeline (2-4 hours)
|
||||||
|
- [ ] Create GitHub Actions workflow for backend
|
||||||
|
- [ ] Configure build, test, and deploy steps
|
||||||
|
- [ ] Set up environment secrets
|
||||||
|
- [ ] Configure branch protection rules
|
||||||
|
- [ ] Test CI/CD pipeline
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Backend Project Created | - | ⏳ |
|
||||||
|
| Database Configured | - | ⏳ |
|
||||||
|
| Docker Setup Complete | - | ⏳ |
|
||||||
|
| CI/CD Pipeline Working | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Initialize .NET 9.0 Web API project
|
||||||
|
- [ ] Configure Program.cs with proper middleware
|
||||||
|
- [ ] Set up appsettings.Development.json, appsettings.Staging.json, appsettings.Production.json
|
||||||
|
- [ ] Create HealthChecks endpoint
|
||||||
|
- [ ] Configure Swagger/OpenAPI
|
||||||
|
- [ ] Set up CORS policy
|
||||||
|
- [ ] Configure logging
|
||||||
|
- [ ] Create error handling middleware
|
||||||
|
- [ ] Create base response wrappers
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Install PostgreSQL locally for development
|
||||||
|
- [ ] Create initial database schema
|
||||||
|
- [ ] Configure EF Core DbContext
|
||||||
|
- [ ] Create first migration
|
||||||
|
- [ ] Apply migration to database
|
||||||
|
- [ ] Create seed data for initial testing
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
- [ ] Create backend Dockerfile
|
||||||
|
- [ ] Create frontend Dockerfile
|
||||||
|
- [ ] Create docker-compose.yml
|
||||||
|
- [ ] Configure Docker volumes
|
||||||
|
- [ ] Set up Docker .env file
|
||||||
|
- [ ] Test Docker containers
|
||||||
|
|
||||||
|
### CI/CD
|
||||||
|
- [ ] Create .github/workflows/ directory
|
||||||
|
- [ ] Create backend CI workflow
|
||||||
|
- [ ] Create frontend CI workflow
|
||||||
|
- [ ] Configure deployment workflow
|
||||||
|
- [ ] Set up GitHub secrets
|
||||||
|
- [ ] Test workflows
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- None - This is the foundational feature
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- .NET 9.0 SDK
|
||||||
|
- PostgreSQL 15+
|
||||||
|
- Docker & Docker Compose
|
||||||
|
- GitHub account with repository access
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] None identified
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Infrastructure-Specific Criteria
|
||||||
|
- [ ] .NET 9.0 backend project builds successfully
|
||||||
|
- [ ] PostgreSQL database is accessible and configured
|
||||||
|
- [ ] Docker containers build and run without errors
|
||||||
|
- [ ] CI/CD pipeline runs successfully on push
|
||||||
|
- [ ] Development environment is reproducible by new team members
|
||||||
|
- [ ] Health checks pass for all services
|
||||||
|
- [ ] Database migrations can be applied cleanly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Infrastructure-Specific Tests
|
||||||
|
- [ ] Verify .NET 9.0 project structure
|
||||||
|
- [ ] Test database connection and queries
|
||||||
|
- [ ] Test Docker build process
|
||||||
|
- [ ] Test Docker Compose startup
|
||||||
|
- [ ] Test CI/CD pipeline execution
|
||||||
|
- [ ] Test health check endpoints
|
||||||
|
- [ ] Test database migration process
|
||||||
|
- [ ] Test backup and restore procedures
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Use PostgreSQL over SQLite | Better for production, supports more features, widely used |
|
||||||
|
| May 31, 2025 | Use Docker Compose | Simplified local development setup |
|
||||||
|
| May 31, 2025 | GitHub Actions for CI/CD | Native GitHub integration, free for public repos |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Connection strings should use environment variables, not hardcoded values
|
||||||
|
- Docker volumes should be used for PostgreSQL data to persist between restarts
|
||||||
|
- Health checks should verify database connectivity
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Docker on Windows may have volume mounting issues - use WSL2
|
||||||
|
- ⚠️ PostgreSQL container needs explicit volume for data persistence
|
||||||
|
- ⚠️ EF Core tools need to be installed for migrations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Development: [How to Run Vibe](../development/how-to-run-vibe.md)
|
||||||
|
- Application Plan: [Application Plan](../architecture/application-plan.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
361
docs/features/lesson-management.md
Normal file
361
docs/features/lesson-management.md
Normal file
|
|
@ -0,0 +1,361 @@
|
||||||
|
# Feature: Lesson & Content Management
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: High
|
||||||
|
> **Estimate**: 10-16 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, User Authentication, Vocabulary System, Quiz System, Story Integration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement the core lesson management system that allows users to browse, access, and progress through structured German lessons organized by CEFR levels (A1-C1).
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a learner, I want to access structured lessons organized by difficulty level so that I can systematically learn German from A1 to C1.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Lessons are organized by CEFR levels (A1, A2, B1, B2, C1)
|
||||||
|
- [ ] Lessons within each level must be completed in order
|
||||||
|
- [ ] Each lesson contains vocabulary, grammar, story segment, and exercises
|
||||||
|
- [ ] Users can view lesson details and content
|
||||||
|
- [ ] Progress is tracked per user per lesson
|
||||||
|
- [ ] Lessons unlock sequentially based on quiz completion (80% passing score)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | Create/Read/Update/Delete lessons (Admin) | High |
|
||||||
|
| FR-002 | List lessons by level | High |
|
||||||
|
| FR-003 | Get lesson details with all content | High |
|
||||||
|
| FR-004 | Track user progress through lessons | High |
|
||||||
|
| FR-005 | Enforce sequential lesson unlocking | High |
|
||||||
|
| FR-006 | Lesson contains: vocabulary, grammar, story, reading, listening, speaking, writing, quiz | High |
|
||||||
|
| FR-007 | Calculate level completion percentage | Medium |
|
||||||
|
| FR-008 | Admin can reorder lessons | Low |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Lesson listing < 200ms
|
||||||
|
- Performance: Lesson details < 500ms
|
||||||
|
- Security: Only authorized admins can create/edit lessons
|
||||||
|
- Data Integrity: Lesson order must be maintained
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: LessonsController, LessonService, LevelService
|
||||||
|
- **Database**: Levels, Lessons, UserProgress tables
|
||||||
|
- **Models**: Level, Lesson, LessonDto, LevelDto
|
||||||
|
- **Frontend**: LessonPage, LessonList, LessonCard components
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
1. User requests lessons for A1 level
|
||||||
|
2. Backend queries Lessons table filtered by LevelId = A1
|
||||||
|
3. Backend checks UserProgress to determine which lessons are unlocked
|
||||||
|
4. Backend returns list of lessons with locked/unlocked status
|
||||||
|
5. User selects a lesson
|
||||||
|
6. Backend returns full lesson content (vocabulary, grammar, story, etc.)
|
||||||
|
7. User completes lesson activities
|
||||||
|
8. User takes quiz
|
||||||
|
9. If quiz passed (80%), mark lesson as completed and unlock next lesson
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
| Endpoint | Method | Description | Auth Required |
|
||||||
|
|----------|--------|-------------|----------------|
|
||||||
|
| `/api/levels` | GET | List all CEFR levels | Yes |
|
||||||
|
| `/api/levels/{levelId}/lessons` | GET | List lessons for a specific level | Yes |
|
||||||
|
| `/api/lessons/{id}` | GET | Get full lesson details with all content | Yes |
|
||||||
|
| `/api/lessons` | POST | Create new lesson (Admin) | Yes |
|
||||||
|
| `/api/lessons/{id}` | PUT | Update lesson (Admin) | Yes |
|
||||||
|
| `/api/lessons/{id}` | DELETE | Delete lesson (Admin) | Yes |
|
||||||
|
| `/api/lessons/{id}/reorder` | POST | Reorder lessons (Admin) | Yes |
|
||||||
|
|
||||||
|
### Database Schema (from application-plan.md)
|
||||||
|
```sql
|
||||||
|
-- Levels table
|
||||||
|
CREATE TABLE Levels (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
Name VARCHAR(10) UNIQUE NOT NULL, -- e.g., "A1", "A2"
|
||||||
|
Description TEXT,
|
||||||
|
Order INT UNIQUE NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Lessons table
|
||||||
|
CREATE TABLE Lessons (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LevelId INT REFERENCES Levels(Id) ON DELETE CASCADE,
|
||||||
|
Title VARCHAR(100) NOT NULL,
|
||||||
|
Order INT NOT NULL,
|
||||||
|
Topic VARCHAR(100) NOT NULL,
|
||||||
|
UNIQUE(LevelId, Order)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- User Progress table
|
||||||
|
CREATE TABLE UserProgress (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
UserId INT REFERENCES Users(Id) ON DELETE CASCADE,
|
||||||
|
LessonId INT,
|
||||||
|
IsCompleted BOOLEAN DEFAULT FALSE,
|
||||||
|
QuizScore INT,
|
||||||
|
LastAttemptDate TIMESTAMP DEFAULT NOW(),
|
||||||
|
UNIQUE(UserId, LessonId)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lesson Content Structure
|
||||||
|
Each lesson contains:
|
||||||
|
1. **Vocabulary**: 5-10 words with translations, articles, audio
|
||||||
|
2. **Grammar**: Concept explanation with examples and audio
|
||||||
|
3. **Story Segment**: Part of continuous narrative using lesson vocabulary
|
||||||
|
4. **Reading**: Short text with comprehension questions
|
||||||
|
5. **Listening**: Audio exercises with questions
|
||||||
|
6. **Speaking**: Recording exercises
|
||||||
|
7. **Writing**: Open-ended prompts
|
||||||
|
8. **Quiz**: 10-15 questions to test understanding
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Database & Models (2-3 hours)
|
||||||
|
- [ ] Create Level entity and repository
|
||||||
|
- [ ] Create Lesson entity and repository
|
||||||
|
- [ ] Create UserProgress entity and repository
|
||||||
|
- [ ] Set up relationships between entities
|
||||||
|
- [ ] Create migrations for Levels, Lessons, UserProgress
|
||||||
|
- [ ] Seed initial A1 level and lessons
|
||||||
|
|
||||||
|
### Phase 2: Backend Services (3-5 hours)
|
||||||
|
- [ ] Create LevelService with CRUD operations
|
||||||
|
- [ ] Create LessonService with CRUD operations
|
||||||
|
- [ ] Create ProgressService to track user progress
|
||||||
|
- [ ] Implement sequential unlocking logic
|
||||||
|
- [ ] Create DTOs for Level, Lesson, UserProgress
|
||||||
|
- [ ] Create mapping profiles (AutoMapper or manual)
|
||||||
|
|
||||||
|
### Phase 3: API Controllers (2-3 hours)
|
||||||
|
- [ ] Create LevelsController
|
||||||
|
- [ ] Create LessonsController
|
||||||
|
- [ ] Add authorization (Admin for write operations)
|
||||||
|
- [ ] Add validation for lesson data
|
||||||
|
- [ ] Implement proper error handling
|
||||||
|
|
||||||
|
### Phase 4: Business Logic (2-3 hours)
|
||||||
|
- [ ] Implement lesson unlocking logic
|
||||||
|
- [ ] Calculate level completion percentage
|
||||||
|
- [ ] Add next lesson recommendation
|
||||||
|
- [ ] Implement lesson order validation
|
||||||
|
|
||||||
|
### Phase 5: Integration with Other Features (1-2 hours)
|
||||||
|
- [ ] Integrate with Vocabulary system
|
||||||
|
- [ ] Integrate with Story system
|
||||||
|
- [ ] Integrate with Quiz system
|
||||||
|
- [ ] Update user progress on quiz completion
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Database & Models | - | ⏳ |
|
||||||
|
| Backend Services | - | ⏳ |
|
||||||
|
| API Controllers | - | ⏳ |
|
||||||
|
| Business Logic | - | ⏳ |
|
||||||
|
| Integration | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Create Domain/Entities/Level.cs
|
||||||
|
- [ ] Create Domain/Entities/Lesson.cs
|
||||||
|
- [ ] Create Domain/Entities/UserProgress.cs
|
||||||
|
- [ ] Create Domain/Interfaces/ILevelRepository.cs
|
||||||
|
- [ ] Create Domain/Interfaces/ILessonRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/LevelRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/LessonRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/UserProgressRepository.cs
|
||||||
|
- [ ] Create Application/DTOs/LevelDto.cs
|
||||||
|
- [ ] Create Application/DTOs/LessonDto.cs
|
||||||
|
- [ ] Create Application/DTOs/UserProgressDto.cs
|
||||||
|
- [ ] Create Application/Services/LevelService.cs
|
||||||
|
- [ ] Create Application/Services/LessonService.cs
|
||||||
|
- [ ] Create Application/Services/ProgressService.cs
|
||||||
|
- [ ] Create Presentation/Controllers/LevelsController.cs
|
||||||
|
- [ ] Create Presentation/Controllers/LessonsController.cs
|
||||||
|
- [ ] Register services in Program.cs
|
||||||
|
- [ ] Write unit tests for services
|
||||||
|
- [ ] Write integration tests for controllers
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Create migration for Levels table
|
||||||
|
- [ ] Create migration for Lessons table
|
||||||
|
- [ ] Create migration for UserProgress table
|
||||||
|
- [ ] Seed A1 level with initial lessons
|
||||||
|
- [ ] Add indexes for performance
|
||||||
|
|
||||||
|
### Business Logic
|
||||||
|
- [ ] Implement LessonUnlockService
|
||||||
|
- [ ] Implement LevelCompletionCalculator
|
||||||
|
- [ ] Add validation for lesson order
|
||||||
|
- [ ] Add authorization checks
|
||||||
|
|
||||||
|
### Integration
|
||||||
|
- [ ] Integrate with Vocabulary feature
|
||||||
|
- [ ] Integrate with Story feature
|
||||||
|
- [ ] Integrate with Quiz feature
|
||||||
|
- [ ] Update progress when quiz is passed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required (backend project and database)
|
||||||
|
- [User Authentication](user-authentication.md) - Required (for user-specific progress tracking)
|
||||||
|
- Vocabulary System - Required (lesson content)
|
||||||
|
- Story Integration - Required (lesson content)
|
||||||
|
- Quiz System - Required (lesson completion)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Entity Framework Core
|
||||||
|
- AutoMapper (optional, for DTO mapping)
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete
|
||||||
|
- [ ] User Authentication must be complete for progress tracking
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Lesson Management-Specific Criteria
|
||||||
|
- [ ] All CEFR levels (A1-C1) can be created and managed
|
||||||
|
- [ ] Lessons can be created, read, updated, and deleted
|
||||||
|
- [ ] Lessons are properly ordered within levels
|
||||||
|
- [ ] Sequential lesson unlocking works correctly
|
||||||
|
- [ ] User progress is tracked per lesson
|
||||||
|
- [ ] Level completion percentage is calculated correctly
|
||||||
|
- [ ] Next lesson recommendation works
|
||||||
|
- [ ] Admin can reorder lessons
|
||||||
|
- [ ] All lesson content (vocabulary, grammar, story, etc.) can be associated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Lesson Management-Specific Tests
|
||||||
|
|
||||||
|
#### Backend Tests
|
||||||
|
- [ ] Create level → success
|
||||||
|
- [ ] Create level with duplicate name → error
|
||||||
|
- [ ] Get all levels → returns correct list
|
||||||
|
- [ ] Create lesson → success
|
||||||
|
- [ ] Create lesson with duplicate (level, order) → error
|
||||||
|
- [ ] Get lessons by level → returns correct list
|
||||||
|
- [ ] Get lesson by ID → returns correct lesson
|
||||||
|
- [ ] Update lesson → success
|
||||||
|
- [ ] Update lesson order → updates correctly, cascades to other lessons
|
||||||
|
- [ ] Delete lesson → success, updates other lessons' order
|
||||||
|
- [ ] Get user progress for lesson → returns correct status
|
||||||
|
- [ ] Complete lesson → updates progress, unlocks next lesson
|
||||||
|
- [ ] Calculate level completion → returns correct percentage
|
||||||
|
|
||||||
|
#### Business Logic Tests
|
||||||
|
- [ ] Lesson unlocking with completed previous lesson → success
|
||||||
|
- [ ] Lesson unlocking without completed previous lesson → fails
|
||||||
|
- [ ] Level completion with all lessons completed → 100%
|
||||||
|
- [ ] Level completion with some lessons completed → correct %
|
||||||
|
- [ ] Lesson reordering updates all subsequent lessons → correct
|
||||||
|
- [ ] Lesson deletion updates all subsequent lessons → correct
|
||||||
|
|
||||||
|
#### Integration Tests
|
||||||
|
- [ ] Create lesson with vocabulary → both created
|
||||||
|
- [ ] Create lesson with quiz → both created
|
||||||
|
- [ ] Complete lesson → triggers quiz availability
|
||||||
|
- [ ] User progress updates when quiz passed → lesson marked complete
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Sequential lesson unlocking | Ensures users learn foundation before advanced topics |
|
||||||
|
| May 31, 2025 | 80% passing score | Balance between rigor and user frustration |
|
||||||
|
| May 31, 2025 | Lessons organized by CEFR levels | Industry standard for language learning |
|
||||||
|
| May 31, 2025 | Unlimited quiz retakes | Encourages practice without penalty |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Lesson order is critical - use database UNIQUE constraint on (LevelId, Order)
|
||||||
|
- UserProgress table tracks both completion status and quiz scores
|
||||||
|
- Progress calculation: (completed lessons / total lessons in level) * 100
|
||||||
|
- Lesson unlocking: User can access lesson N only if lesson N-1 is completed
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Lesson reordering must update all subsequent lessons' Order values
|
||||||
|
- ⚠️ Deleting a lesson requires updating all lessons with higher Order values
|
||||||
|
- ⚠️ UserProgress.LessonId can be NULL for lessons not yet started
|
||||||
|
- ⚠️ Need to handle case where user hasn't started any lessons in a level
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Feature: [Vocabulary System](vocabulary-system.md)
|
||||||
|
- Feature: [Story Integration](story-integration.md)
|
||||||
|
- Feature: [Quiz System](quiz-system.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
460
docs/features/quiz-system.md
Normal file
460
docs/features/quiz-system.md
Normal file
|
|
@ -0,0 +1,460 @@
|
||||||
|
# Feature: Quiz System
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: High
|
||||||
|
> **Estimate**: 6-10 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, Lesson Management, User Authentication, AI Services (TTS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement a comprehensive quiz system that tests users' understanding of lesson material through various question types, with automatic scoring and progress tracking.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a learner, I want to take quizzes after each lesson to test my understanding and receive immediate feedback on my performance.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Each lesson has an associated quiz
|
||||||
|
- [ ] Quiz contains 10-15 questions of various types
|
||||||
|
- [ ] Question types: Multiple Choice, Fill-in-the-Blank, Listening Comprehension, Matching
|
||||||
|
- [ ] Static difficulty (same questions for all users)
|
||||||
|
- [ ] 80% passing score required to complete lesson
|
||||||
|
- [ ] Unlimited retakes allowed
|
||||||
|
- [ ] Score is recorded in UserProgress table
|
||||||
|
- [ ] Quiz results show which questions were correct/incorrect
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | Create/Read/Update/Delete quizzes (Admin) | High |
|
||||||
|
| FR-002 | Associate quizzes with lessons | High |
|
||||||
|
| FR-003 | Support multiple question types | High |
|
||||||
|
| FR-004 | Support MCQ questions | High |
|
||||||
|
| FR-005 | Support fill-in-the-blank questions | High |
|
||||||
|
| FR-006 | Support listening comprehension questions | High |
|
||||||
|
| FR-007 | Support matching questions | High |
|
||||||
|
| FR-008 | Calculate quiz score and passing status | High |
|
||||||
|
| FR-009 | Record quiz attempts in UserProgress | High |
|
||||||
|
| FR-010 | Return detailed results with correct/incorrect answers | Medium |
|
||||||
|
| FR-011 | Allow unlimited retakes | Medium |
|
||||||
|
| FR-012 | Configurable passing score (default 80%) | Medium |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Quiz loading < 300ms
|
||||||
|
- Performance: Quiz submission < 500ms
|
||||||
|
- Security: Only authorized admins can create/edit quizzes
|
||||||
|
- Data Integrity: Quiz-question relationships must be maintained
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: QuizzesController, QuizService, QuestionService
|
||||||
|
- **Database**: Quizzes, Questions tables
|
||||||
|
- **Models**: Quiz, Question, QuizDto, QuestionDto, AnswerDto, QuizResult
|
||||||
|
- **External**: Coqui TTS (for listening questions audio)
|
||||||
|
- **Frontend**: QuizPage, QuizTab, McqQuestion, FillInBlank, ListeningQuestion, MatchingQuestion components
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
1. User completes lesson activities
|
||||||
|
2. User navigates to quiz for the lesson
|
||||||
|
3. Backend retrieves quiz and questions for the lesson
|
||||||
|
4. Frontend displays quiz to user
|
||||||
|
5. User answers all questions
|
||||||
|
6. Frontend sends answers to backend
|
||||||
|
7. Backend scores quiz and determines pass/fail
|
||||||
|
8. Backend updates UserProgress with score and completion status
|
||||||
|
9. Backend returns detailed results to frontend
|
||||||
|
10. Frontend displays results with feedback
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
| Endpoint | Method | Description | Auth Required |
|
||||||
|
|----------|--------|-------------|----------------|
|
||||||
|
| `/api/quizzes` | GET | List all quizzes | Yes |
|
||||||
|
| `/api/quizzes/{id}` | GET | Get quiz with questions | Yes |
|
||||||
|
| `/api/lessons/{lessonId}/quiz` | GET | Get quiz for a specific lesson | Yes |
|
||||||
|
| `/api/quizzes` | POST | Create new quiz (Admin) | Yes |
|
||||||
|
| `/api/quizzes/{id}` | PUT | Update quiz (Admin) | Yes |
|
||||||
|
| `/api/quizzes/{id}` | DELETE | Delete quiz (Admin) | Yes |
|
||||||
|
| `/api/quizzes/{quizId}/questions` | GET | List questions for a quiz | Yes |
|
||||||
|
| `/api/questions` | POST | Add question to quiz (Admin) | Yes |
|
||||||
|
| `/api/questions/{id}` | PUT | Update question (Admin) | Yes |
|
||||||
|
| `/api/questions/{id}` | DELETE | Delete question (Admin) | Yes |
|
||||||
|
| `/api/quizzes/{quizId}/submit` | POST | Submit quiz answers | Yes |
|
||||||
|
| `/api/quizzes/{quizId}/results` | GET | Get quiz results history | Yes |
|
||||||
|
|
||||||
|
### Database Schema (from application-plan.md)
|
||||||
|
```sql
|
||||||
|
-- Quizzes table
|
||||||
|
CREATE TABLE Quizzes (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE,
|
||||||
|
PassingScore INT DEFAULT 80
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Questions table
|
||||||
|
CREATE TABLE Questions (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
QuizId INT REFERENCES Quizzes(Id) ON DELETE CASCADE,
|
||||||
|
Type VARCHAR(20) NOT NULL CHECK (Type IN ('mcq', 'fill_in', 'listening', 'matching')),
|
||||||
|
Content TEXT NOT NULL,
|
||||||
|
CorrectAnswer TEXT NOT NULL,
|
||||||
|
AudioUrl VARCHAR(255),
|
||||||
|
Options TEXT[], -- For MCQ: ['option1', 'option2']
|
||||||
|
Points INT DEFAULT 1
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Question Types
|
||||||
|
|
||||||
|
#### 1. Multiple Choice (mcq)
|
||||||
|
```csharp
|
||||||
|
{
|
||||||
|
Type: "mcq",
|
||||||
|
Content: "What is the article for 'Buch'?",
|
||||||
|
CorrectAnswer: "das",
|
||||||
|
Options: ["der", "die", "das"],
|
||||||
|
Points: 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Fill-in-the-Blank (fill_in)
|
||||||
|
```csharp
|
||||||
|
{
|
||||||
|
Type: "fill_in",
|
||||||
|
Content: "Anna _____ um 7 Uhr auf.",
|
||||||
|
CorrectAnswer: "steht",
|
||||||
|
Options: null,
|
||||||
|
Points: 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Listening Comprehension (listening)
|
||||||
|
```csharp
|
||||||
|
{
|
||||||
|
Type: "listening",
|
||||||
|
Content: "What did you hear?",
|
||||||
|
CorrectAnswer: "This is a book.",
|
||||||
|
AudioUrl: "/audio/quiz/1.wav",
|
||||||
|
Options: ["This is a book.", "This is a cat."],
|
||||||
|
Points: 2 // More points for harder questions
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Matching (matching)
|
||||||
|
```csharp
|
||||||
|
{
|
||||||
|
Type: "matching",
|
||||||
|
Content: "Match the word to its article",
|
||||||
|
CorrectAnswer: "der", // For "Buch" in this case
|
||||||
|
Options: ["Buch", "Frau", "Kind"], // Words to match
|
||||||
|
Points: 1
|
||||||
|
}
|
||||||
|
// Note: Matching questions may need special handling
|
||||||
|
// Alternative: Store as JSON with pairs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Database & Models (2-3 hours)
|
||||||
|
- [ ] Create Quiz entity
|
||||||
|
- [ ] Create Question entity
|
||||||
|
- [ ] Create QuizDto, QuestionDto, AnswerDto
|
||||||
|
- [ ] Create QuizResult model
|
||||||
|
- [ ] Create IQuizRepository interface
|
||||||
|
- [ ] Create IQuestionRepository interface
|
||||||
|
- [ ] Create repository implementations
|
||||||
|
- [ ] Create migrations for Quizzes and Questions tables
|
||||||
|
|
||||||
|
### Phase 2: Backend Services (2-3 hours)
|
||||||
|
- [ ] Create QuizService with CRUD operations
|
||||||
|
- [ ] Create QuestionService with CRUD operations
|
||||||
|
- [ ] Create QuizSubmissionService for handling answers
|
||||||
|
- [ ] Implement scoring logic
|
||||||
|
- [ ] Implement pass/fail determination
|
||||||
|
- [ ] Update UserProgress on quiz completion
|
||||||
|
- [ ] Create mapping between entities and DTOs
|
||||||
|
|
||||||
|
### Phase 3: API Controllers (2 hours)
|
||||||
|
- [ ] Create QuizzesController
|
||||||
|
- [ ] Create QuestionsController
|
||||||
|
- [ ] Implement quiz submission endpoint
|
||||||
|
- [ ] Implement results endpoint
|
||||||
|
- [ ] Add authorization (Admin for write operations)
|
||||||
|
- [ ] Add validation for quiz data
|
||||||
|
|
||||||
|
### Phase 4: Question Type Implementation (2 hours)
|
||||||
|
- [ ] Implement MCQ question handling
|
||||||
|
- [ ] Implement fill-in-the-blank question handling
|
||||||
|
- [ ] Implement listening comprehension with audio
|
||||||
|
- [ ] Implement matching question handling
|
||||||
|
- [ ] Add audio generation for listening questions
|
||||||
|
|
||||||
|
### Phase 5: Frontend Integration (2 hours)
|
||||||
|
- [ ] Create QuizPage component
|
||||||
|
- [ ] Create QuizTab component
|
||||||
|
- [ ] Create McqQuestion component
|
||||||
|
- [ ] Create FillInBlank component
|
||||||
|
- [ ] Create ListeningQuestion component
|
||||||
|
- [ ] Create MatchingQuestion component
|
||||||
|
- [ ] Create QuizResults component
|
||||||
|
- [ ] Add quiz to LessonPage
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Database & Models | - | ⏳ |
|
||||||
|
| Backend Services | - | ⏳ |
|
||||||
|
| API Controllers | - | ⏳ |
|
||||||
|
| Question Type Implementation | - | ⏳ |
|
||||||
|
| Frontend Integration | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Create Domain/Entities/Quiz.cs
|
||||||
|
- [ ] Create Domain/Entities/Question.cs
|
||||||
|
- [ ] Create Application/DTOs/QuizDto.cs
|
||||||
|
- [ ] Create Application/DTOs/QuestionDto.cs
|
||||||
|
- [ ] Create Application/DTOs/AnswerDto.cs
|
||||||
|
- [ ] Create Application/DTOs/QuizResult.cs
|
||||||
|
- [ ] Create Domain/Interfaces/IQuizRepository.cs
|
||||||
|
- [ ] Create Domain/Interfaces/IQuestionRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/QuizRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/QuestionRepository.cs
|
||||||
|
- [ ] Create Application/Services/QuizService.cs
|
||||||
|
- [ ] Create Application/Services/QuestionService.cs
|
||||||
|
- [ ] Create Application/Services/QuizSubmissionService.cs
|
||||||
|
- [ ] Create Presentation/Controllers/QuizzesController.cs
|
||||||
|
- [ ] Create Presentation/Controllers/QuestionsController.cs
|
||||||
|
- [ ] Integrate with UserProgress from Lesson Management
|
||||||
|
- [ ] Register services in Program.cs
|
||||||
|
- [ ] Write unit tests for services
|
||||||
|
- [ ] Write integration tests for controllers
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Create migration for Quizzes table
|
||||||
|
- [ ] Create migration for Questions table
|
||||||
|
- [ ] Add foreign key from Quizzes to Lessons
|
||||||
|
- [ ] Add indexes for QuizId, Type
|
||||||
|
- [ ] Apply migrations
|
||||||
|
|
||||||
|
### Audio Generation
|
||||||
|
- [ ] Extend Coqui TTS service for quiz questions
|
||||||
|
- [ ] Generate audio for listening comprehension questions
|
||||||
|
- [ ] Store audio files with quiz question IDs
|
||||||
|
|
||||||
|
### Question Types
|
||||||
|
- [ ] Implement MCQ answer validation
|
||||||
|
- [ ] Implement fill-in-the-blank answer validation
|
||||||
|
- [ ] Implement listening comprehension answer validation
|
||||||
|
- [ ] Implement matching answer validation
|
||||||
|
- [ ] Add case-insensitive comparison where appropriate
|
||||||
|
- [ ] Add whitespace trimming for answers
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] Create pages/QuizPage.tsx
|
||||||
|
- [ ] Create components/QuizTab.tsx
|
||||||
|
- [ ] Create components/questions/McqQuestion.tsx
|
||||||
|
- [ ] Create components/questions/FillInBlank.tsx
|
||||||
|
- [ ] Create components/questions/ListeningQuestion.tsx
|
||||||
|
- [ ] Create components/questions/MatchingQuestion.tsx
|
||||||
|
- [ ] Create components/QuizResults.tsx
|
||||||
|
- [ ] Create hooks/useQuiz.ts
|
||||||
|
- [ ] Integrate AudioPlayer for listening questions
|
||||||
|
- [ ] Add quiz timer (optional)
|
||||||
|
- [ ] Add progress indicator
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required
|
||||||
|
- [Lesson Management](lesson-management.md) - Required (quizzes associated with lessons)
|
||||||
|
- [User Authentication](user-authentication.md) - Required (for tracking progress)
|
||||||
|
- [AI Services - TTS](ai-services.md) - Required (for listening question audio)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Entity Framework Core
|
||||||
|
- AutoMapper (optional)
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete
|
||||||
|
- [ ] Lesson Management must be complete
|
||||||
|
- [ ] User Authentication must be complete for progress tracking
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Quiz-Specific Criteria
|
||||||
|
- [ ] Quizzes can be created, read, updated, and deleted
|
||||||
|
- [ ] Questions can be added to, updated in, and removed from quizzes
|
||||||
|
- [ ] All question types work correctly (MCQ, Fill-in, Listening, Matching)
|
||||||
|
- [ ] Quiz submission works and returns score
|
||||||
|
- [ ] Pass/fail determination is correct (80% threshold)
|
||||||
|
- [ ] User progress is updated on quiz completion
|
||||||
|
- [ ] Quiz results show correct/incorrect answers
|
||||||
|
- [ ] Unlimited retakes are allowed
|
||||||
|
- [ ] Audio for listening questions is generated and accessible
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Quiz-Specific Tests
|
||||||
|
|
||||||
|
#### Backend Tests
|
||||||
|
- [ ] Create quiz → success
|
||||||
|
- [ ] Create quiz with invalid lesson → error
|
||||||
|
- [ ] Get quiz by ID → returns correct quiz with questions
|
||||||
|
- [ ] Get quiz by lesson → returns correct quiz
|
||||||
|
- [ ] Add question to quiz → success
|
||||||
|
- [ ] Add MCQ question → success
|
||||||
|
- [ ] Add fill-in question → success
|
||||||
|
- [ ] Add listening question → success
|
||||||
|
- [ ] Add matching question → success
|
||||||
|
- [ ] Update question → success
|
||||||
|
- [ ] Delete question → success
|
||||||
|
- [ ] Submit quiz with all correct answers → 100% score
|
||||||
|
- [ ] Submit quiz with some correct answers → partial score
|
||||||
|
- [ ] Submit quiz with all wrong answers → 0% score
|
||||||
|
- [ ] Submit quiz with passing score → user progress updated
|
||||||
|
- [ ] Submit quiz with failing score → user progress not updated
|
||||||
|
- [ ] Delete quiz → cascades to questions
|
||||||
|
|
||||||
|
#### Question Type Tests
|
||||||
|
- [ ] MCQ: Correct answer → scored correctly
|
||||||
|
- [ ] MCQ: Incorrect answer → scored incorrectly
|
||||||
|
- [ ] Fill-in: Exact match → scored correctly
|
||||||
|
- [ ] Fill-in: Case-insensitive match → scored correctly
|
||||||
|
- [ ] Fill-in: Whitespace variation → scored correctly
|
||||||
|
- [ ] Fill-in: Close but wrong → scored incorrectly
|
||||||
|
- [ ] Listening: Correct transcription → scored correctly
|
||||||
|
- [ ] Listening: Incorrect transcription → scored incorrectly
|
||||||
|
- [ ] Matching: All pairs correct → scored correctly
|
||||||
|
- [ ] Matching: Some pairs correct → partial score
|
||||||
|
|
||||||
|
#### Business Logic Tests
|
||||||
|
- [ ] Scoring with default points → correct calculation
|
||||||
|
- [ ] Scoring with custom points → correct calculation
|
||||||
|
- [ ] Pass/fail at 80% threshold → correct determination
|
||||||
|
- [ ] Pass/fail at exactly 80% → passes
|
||||||
|
- [ ] Pass/fail at 79% → fails
|
||||||
|
- [ ] User progress updates on first pass → lesson marked complete
|
||||||
|
- [ ] User progress updates on subsequent pass → no change (already complete)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Static difficulty | Simpler implementation, consistent experience for all users |
|
||||||
|
| May 31, 2025 | 80% passing score | Industry standard, rigorous but achievable |
|
||||||
|
| May 31, 2025 | Unlimited retakes | Encourages practice, reduces anxiety |
|
||||||
|
| May 31, 2025 | Multiple question types | Varied testing, caters to different learning styles |
|
||||||
|
| May 31, 2025 | Store AudioUrl on questions | Enables listening comprehension questions |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Questions table uses PostgreSQL TEXT[] array type for Options
|
||||||
|
- Each question has a Points value for weighted scoring
|
||||||
|
- Quiz.PassingScore is the percentage required (default 80)
|
||||||
|
- QuizResult should include: Passed, Score, TotalPoints, QuestionResults[]
|
||||||
|
- QuestionResults should include: QuestionId, UserAnswer, CorrectAnswer, IsCorrect, PointsEarned
|
||||||
|
|
||||||
|
### Question Type Validation Logic
|
||||||
|
|
||||||
|
#### MCQ
|
||||||
|
- UserAnswer must exactly match one of the Options
|
||||||
|
- Case-insensitive comparison recommended
|
||||||
|
|
||||||
|
#### Fill-in-the-Blank
|
||||||
|
- UserAnswer compared to CorrectAnswer
|
||||||
|
- Trim whitespace from both before comparison
|
||||||
|
- Case-insensitive comparison recommended
|
||||||
|
- Consider allowing minor variations (e.g., "steht" vs "stehen")
|
||||||
|
|
||||||
|
#### Listening Comprehension
|
||||||
|
- UserAnswer must exactly match CorrectAnswer (or one of Options for MCQ-style listening)
|
||||||
|
- AudioUrl must be present and valid
|
||||||
|
|
||||||
|
#### Matching
|
||||||
|
- Need to handle multiple pairs
|
||||||
|
- Consider storing as: `{ pairs: [{left: "Buch", right: "das"}, ...] }`
|
||||||
|
- Validate that all pairs are correct
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Listening questions require audio generation - can be slow
|
||||||
|
- ⚠️ Fill-in-the-blank needs careful validation (accents, case, etc.)
|
||||||
|
- ⚠️ Matching questions need special data structure
|
||||||
|
- ⚠️ Quiz deletion must cascade to Questions (ON DELETE CASCADE)
|
||||||
|
- ⚠️ Question updates must maintain quiz integrity
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Feature: [Lesson Management](lesson-management.md)
|
||||||
|
- Feature: [User Authentication](user-authentication.md)
|
||||||
|
- Feature: [AI Services](ai-services.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
411
docs/features/story-integration.md
Normal file
411
docs/features/story-integration.md
Normal file
|
|
@ -0,0 +1,411 @@
|
||||||
|
# Feature: Story Integration
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: High
|
||||||
|
> **Estimate**: 8-12 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, Lesson Management, AI Services (Mistral, TTS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement a continuous story narrative that unlocks segment by segment as users complete lessons, with AI-generated content tailored to each level and lesson's vocabulary.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a learner, I want to follow a continuous story that uses the vocabulary and grammar I'm learning, so that I can see the language in context and stay motivated through narrative progression.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Each level has a continuous story (e.g., A1: "A Week in the Life of Anna")
|
||||||
|
- [ ] Story is divided into segments, one per lesson
|
||||||
|
- [ ] Story segments unlock after completing the associated lesson's quiz
|
||||||
|
- [ ] Story content uses only vocabulary and grammar from completed lessons
|
||||||
|
- [ ] Each story segment has associated audio (Coqui TTS)
|
||||||
|
- [ ] Users can click on words to see translations
|
||||||
|
- [ ] Story progress is tracked separately from lesson progress
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | Create/Read/Update/Delete story segments (Admin) | High |
|
||||||
|
| FR-002 | Associate story segments with levels and lessons | High |
|
||||||
|
| FR-003 | Generate story content using Mistral-Medium AI | High |
|
||||||
|
| FR-004 | Generate audio for story segments using Coqui TTS | High |
|
||||||
|
| FR-005 | Sequential story unlocking based on lesson completion | High |
|
||||||
|
| FR-006 | Display story with clickable words for translations | High |
|
||||||
|
| FR-007 | Track story progress per user | Medium |
|
||||||
|
| FR-008 | Support multiple stories per level (optional) | Low |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Story segment loading < 300ms
|
||||||
|
- Storage: Audio files ~100-500KB per segment
|
||||||
|
- Security: Only admins can create/edit story segments
|
||||||
|
- Data Integrity: Story-level-lesson associations must be valid
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: StoryController, StoryService, StoryGenerationService
|
||||||
|
- **Database**: StorySegments table
|
||||||
|
- **Models**: StorySegment, StorySegmentDto, StoryGenerationRequest
|
||||||
|
- **External**: Mistral-Medium API, Coqui TTS
|
||||||
|
- **Frontend**: StoryPage, StoryTab, StorySegment, StoryPlayer components
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
1. Admin triggers story generation for a level
|
||||||
|
2. Backend calls Mistral-Medium with vocabulary from all lessons in level
|
||||||
|
3. Mistral returns story text divided into segments
|
||||||
|
4. For each segment:
|
||||||
|
a. Store in StorySegments table
|
||||||
|
b. Associate with level and lesson
|
||||||
|
c. Generate audio using Coqui TTS
|
||||||
|
d. Save audio file and update AudioUrl
|
||||||
|
5. User completes lesson quiz (80%+)
|
||||||
|
6. Backend unlocks next story segment for user
|
||||||
|
7. User reads/listens to story segment
|
||||||
|
8. User can click on words to see translations
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
| Endpoint | Method | Description | Auth Required |
|
||||||
|
|----------|--------|-------------|----------------|
|
||||||
|
| `/api/story/levels` | GET | List levels with stories | Yes |
|
||||||
|
| `/api/story/{levelId}/segments` | GET | List story segments for a level | Yes |
|
||||||
|
| `/api/story/segments/{id}` | GET | Get specific story segment | Yes |
|
||||||
|
| `/api/story/segments` | POST | Create/update story segment (Admin) | Yes |
|
||||||
|
| `/api/story/segments/{id}` | DELETE | Delete story segment (Admin) | Yes |
|
||||||
|
| `/api/story/generate` | POST | Generate story for level (Admin) | Yes |
|
||||||
|
| `/api/story/{levelId}/progress` | GET | Get user's story progress for level | Yes |
|
||||||
|
| `/api/story/segments/{id}/audio` | GET | Get audio file for segment | Yes |
|
||||||
|
|
||||||
|
### Database Schema (from application-plan.md)
|
||||||
|
```sql
|
||||||
|
CREATE TABLE StorySegments (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LevelId INT REFERENCES Levels(Id) ON DELETE CASCADE,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE SET NULL,
|
||||||
|
Content TEXT NOT NULL,
|
||||||
|
AudioUrl VARCHAR(255),
|
||||||
|
Order INT NOT NULL,
|
||||||
|
UNIQUE(LevelId, Order)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Story Generation Prompt
|
||||||
|
```
|
||||||
|
Write a 2–3 paragraph story about daily life for a German {level} learner.
|
||||||
|
Use only {level} vocabulary and grammar (present tense, basic nouns/verbs).
|
||||||
|
Include the following words: {vocabularyList}.
|
||||||
|
Theme: "{theme}".
|
||||||
|
Divide the story into {segmentCount} segments, one for each lesson.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example Story Segment (from application-plan.md)
|
||||||
|
```
|
||||||
|
Id: 1
|
||||||
|
LevelId: 1 (A1)
|
||||||
|
LessonId: 1
|
||||||
|
Content: "Anna steht jeden Morgen um 7 Uhr auf. Sie geht ins Badezimmer und wäscht sich das Gesicht. Dann frühstückt sie in der Küche. Sie isst ein Brot und trinkt einen Kaffee."
|
||||||
|
AudioUrl: "/audio/story/1.wav"
|
||||||
|
Order: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Database & Models (2 hours)
|
||||||
|
- [ ] Create StorySegment entity
|
||||||
|
- [ ] Create StorySegmentDto
|
||||||
|
- [ ] Create StoryGenerationRequest DTO
|
||||||
|
- [ ] Create IStoryRepository interface
|
||||||
|
- [ ] Create StoryRepository implementation
|
||||||
|
- [ ] Create migration for StorySegments table
|
||||||
|
- [ ] Add relationships to Level and Lesson entities
|
||||||
|
|
||||||
|
### Phase 2: Backend Services (2-3 hours)
|
||||||
|
- [ ] Create StoryService with CRUD operations
|
||||||
|
- [ ] Create StoryGenerationService for AI integration
|
||||||
|
- [ ] Implement Mistral-Medium API client
|
||||||
|
- [ ] Implement segment generation logic
|
||||||
|
- [ ] Create story segment ordering logic
|
||||||
|
- [ ] Write unit tests for services
|
||||||
|
|
||||||
|
### Phase 3: AI Integration (2-3 hours)
|
||||||
|
- [ ] Configure Mistral-Medium API client
|
||||||
|
- [ ] Create prompt templates for each level
|
||||||
|
- [ ] Implement vocabulary extraction from lessons
|
||||||
|
- [ ] Implement story text segmentation
|
||||||
|
- [ ] Handle AI API errors gracefully
|
||||||
|
- [ ] Add retry logic for failed generations
|
||||||
|
|
||||||
|
### Phase 4: Audio Generation (2 hours)
|
||||||
|
- [ ] Integrate with Coqui TTS service
|
||||||
|
- [ ] Generate audio for each story segment
|
||||||
|
- [ ] Store audio files with consistent naming
|
||||||
|
- [ ] Update StorySegment.AudioUrl after generation
|
||||||
|
- [ ] Add audio file serving endpoint
|
||||||
|
|
||||||
|
### Phase 5: Frontend Integration (2-3 hours)
|
||||||
|
- [ ] Create StoryPage component
|
||||||
|
- [ ] Create StoryTab component
|
||||||
|
- [ ] Create StorySegment component
|
||||||
|
- [ ] Create StoryPlayer component with audio
|
||||||
|
- [ ] Implement word click-to-translate functionality
|
||||||
|
- [ ] Add story progress tracking
|
||||||
|
- [ ] Integrate with LessonPage
|
||||||
|
|
||||||
|
### Phase 6: User Progress (1-2 hours)
|
||||||
|
- [ ] Track which story segments user has unlocked
|
||||||
|
- [ ] Update unlock status when lesson is completed
|
||||||
|
- [ ] Display locked segments as "coming soon"
|
||||||
|
- [ ] Show progress through story
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Database & Models | - | ⏳ |
|
||||||
|
| Backend Services | - | ⏳ |
|
||||||
|
| AI Integration | - | ⏳ |
|
||||||
|
| Audio Generation | - | ⏳ |
|
||||||
|
| Frontend Integration | - | ⏳ |
|
||||||
|
| User Progress | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Create Domain/Entities/StorySegment.cs
|
||||||
|
- [ ] Create Application/DTOs/StorySegmentDto.cs
|
||||||
|
- [ ] Create Application/DTOs/StoryGenerationRequest.cs
|
||||||
|
- [ ] Create Domain/Interfaces/IStoryRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/StoryRepository.cs
|
||||||
|
- [ ] Create Application/Services/StoryService.cs
|
||||||
|
- [ ] Create Application/Services/StoryGenerationService.cs
|
||||||
|
- [ ] Create Application/Services/MistralClientService.cs
|
||||||
|
- [ ] Create Presentation/Controllers/StoryController.cs
|
||||||
|
- [ ] Update Level and Lesson entities with StorySegment relationships
|
||||||
|
- [ ] Register services in Program.cs
|
||||||
|
- [ ] Write unit tests
|
||||||
|
- [ ] Write integration tests
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Create migration for StorySegments table
|
||||||
|
- [ ] Add foreign keys to Levels and Lessons
|
||||||
|
- [ ] Add indexes for LevelId, LessonId, Order
|
||||||
|
- [ ] Apply migration
|
||||||
|
|
||||||
|
### AI Integration
|
||||||
|
- [ ] Set up Mistral API client with configuration
|
||||||
|
- [ ] Create prompt templates for each CEFR level
|
||||||
|
- [ ] Implement vocabulary extraction from lessons
|
||||||
|
- [ ] Implement story segmentation logic
|
||||||
|
- [ ] Add error handling for Mistral API
|
||||||
|
- [ ] Add rate limiting/caching for Mistral calls
|
||||||
|
|
||||||
|
### Audio Generation
|
||||||
|
- [ ] Extend Coqui TTS service for story segments
|
||||||
|
- [ ] Implement batch audio generation
|
||||||
|
- [ ] Create audio file storage structure
|
||||||
|
- [ ] Add audio serving endpoint
|
||||||
|
- [ ] Implement audio cleanup mechanism
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] Create pages/StoryPage.tsx
|
||||||
|
- [ ] Create components/StoryTab.tsx
|
||||||
|
- [ ] Create components/StorySegment.tsx
|
||||||
|
- [ ] Create components/StoryPlayer.tsx
|
||||||
|
- [ ] Create hooks/useStory.ts
|
||||||
|
- [ ] Create hooks/useStoryAudio.ts
|
||||||
|
- [ ] Implement word translation on click
|
||||||
|
- [ ] Add story progress indicator
|
||||||
|
- [ ] Add navigation between segments
|
||||||
|
|
||||||
|
### User Progress
|
||||||
|
- [ ] Extend UserProgress or create StoryProgress table
|
||||||
|
- [ ] Implement unlock logic when lesson completed
|
||||||
|
- [ ] Create endpoint to get user's story progress
|
||||||
|
- [ ] Add locked segment UI state
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required
|
||||||
|
- [Lesson Management](lesson-management.md) - Required (story segments associated with lessons/levels)
|
||||||
|
- [AI Services](ai-services.md) - Required (Mistral for generation, Coqui for audio)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Mistral-Medium API access
|
||||||
|
- Coqui TTS Python library
|
||||||
|
- Entity Framework Core
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete
|
||||||
|
- [ ] Lesson Management must be complete
|
||||||
|
- [ ] AI Services must be configured
|
||||||
|
- [ ] Mistral API key required
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Story-Specific Criteria
|
||||||
|
- [ ] Story segments can be created, read, updated, and deleted
|
||||||
|
- [ ] Stories are associated with levels and lessons
|
||||||
|
- [ ] Story content is generated using Mistral-Medium
|
||||||
|
- [ ] Story audio is generated using Coqui TTS
|
||||||
|
- [ ] Story segments unlock sequentially with lesson completion
|
||||||
|
- [ ] Users can view unlocked story segments
|
||||||
|
- [ ] Users can listen to story audio
|
||||||
|
- [ ] Users can click on words to see translations
|
||||||
|
- [ ] Story progress is tracked per user
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Story-Specific Tests
|
||||||
|
|
||||||
|
#### Backend Tests
|
||||||
|
- [ ] Create story segment → success
|
||||||
|
- [ ] Create story segment with invalid level → error
|
||||||
|
- [ ] Get story segments by level → returns correct list
|
||||||
|
- [ ] Get story segment by ID → returns correct segment
|
||||||
|
- [ ] Update story segment → success
|
||||||
|
- [ ] Delete story segment → success
|
||||||
|
- [ ] Generate story with Mistral → returns valid story text
|
||||||
|
- [ ] Generate story with vocabulary list → includes all words
|
||||||
|
- [ ] Generate audio for story segment → creates audio file
|
||||||
|
- [ ] Get user's story progress → returns correct status
|
||||||
|
|
||||||
|
#### AI Tests
|
||||||
|
- [ ] Mistral generates valid German story for A1 level
|
||||||
|
- [ ] Mistral generates story with all requested vocabulary
|
||||||
|
- [ ] Mistral handles different CEFR levels appropriately
|
||||||
|
- [ ] Coqui TTS generates clear audio for story text
|
||||||
|
- [ ] Coqui TTS handles long story segments
|
||||||
|
- [ ] Coqui TTS handles German special characters (umlauts, ß)
|
||||||
|
|
||||||
|
#### Frontend Tests
|
||||||
|
- [ ] Story page loads and displays segments
|
||||||
|
- [ ] Audio plays for story segment
|
||||||
|
- [ ] Word click shows translation
|
||||||
|
- [ ] Navigation between segments works
|
||||||
|
- [ ] Locked segments are displayed as "coming soon"
|
||||||
|
- [ ] Story progress is displayed correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | One story per level for MVP | Simpler implementation, can expand later |
|
||||||
|
| May 31, 2025 | Segment per lesson | Natural progression, matches lesson structure |
|
||||||
|
| May 31, 2025 | Generate audio for all segments | Essential for accessibility and pronunciation |
|
||||||
|
| May 31, 2025 | Use Mistral-Medium | High-quality, cost-effective for this use case |
|
||||||
|
| May 31, 2025 | Click-to-translate words | Enhances learning without disrupting flow |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- StorySegments.LessonId can be NULL for intro/conclusion segments
|
||||||
|
- Order field ensures segments appear in correct sequence
|
||||||
|
- UNIQUE(LevelId, Order) prevents duplicate ordering
|
||||||
|
- Content should be stored as plain text, formatted on frontend
|
||||||
|
- Audio files should be named: `/audio/story/{levelId}-{order}.wav`
|
||||||
|
|
||||||
|
### Prompt Engineering
|
||||||
|
Different prompts for different levels:
|
||||||
|
- **A1**: Simple present tense, basic vocabulary, short sentences
|
||||||
|
- **A2**: Present, past, future tense, expanded vocabulary
|
||||||
|
- **B1**: Complex sentences, subordinate clauses, broader topics
|
||||||
|
- **B2/C1**: Advanced grammar, idiomatic expressions, nuanced topics
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Mistral API has rate limits - implement caching
|
||||||
|
- ⚠️ AI generation may produce non-A1 vocabulary - need validation
|
||||||
|
- ⚠️ Long stories may exceed token limits - need segmentation
|
||||||
|
- ⚠️ Audio generation for long segments may be slow
|
||||||
|
- ⚠️ Need to handle cases where vocabulary list is empty
|
||||||
|
|
||||||
|
### Example Prompts by Level
|
||||||
|
|
||||||
|
**A1 Prompt:**
|
||||||
|
```
|
||||||
|
Write a 2-3 paragraph story about daily life in Germany for an A1 learner.
|
||||||
|
Use only A1 vocabulary and simple present tense sentences.
|
||||||
|
Include these words: {vocabularyList}
|
||||||
|
Theme: {theme}
|
||||||
|
```
|
||||||
|
|
||||||
|
**B1 Prompt:**
|
||||||
|
```
|
||||||
|
Write a 3-4 paragraph story about {theme} for a B1 German learner.
|
||||||
|
Use B1-level vocabulary and grammar including present, past, and future tenses.
|
||||||
|
Include these words: {vocabularyList}
|
||||||
|
Make the story engaging and suitable for adult learners.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Feature: [Lesson Management](lesson-management.md)
|
||||||
|
- Feature: [AI Services](ai-services.md)
|
||||||
|
- Reference: [Mistral AI API](https://docs.mistral.ai/)
|
||||||
|
- Reference: [Coqui TTS](https://github.com/coqui-ai/TTS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
187
docs/features/template.md
Normal file
187
docs/features/template.md
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
# Feature: [Feature Name]
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: Medium
|
||||||
|
> **Complexity**: Medium
|
||||||
|
> **Estimate**: 3 days
|
||||||
|
> **Assignee**: [Your Name]
|
||||||
|
> **Created**: [YYYY-MM-DD]
|
||||||
|
> **Target Completion**: [YYYY-MM-DD]
|
||||||
|
> **PR**: [Link to Pull Request]
|
||||||
|
> **Related Features**: [List of dependent/related features]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
[Brief description of what this feature does and why it's needed]
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
[As a [user type], I want to [action] so that [benefit]]
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Criterion 1
|
||||||
|
- [ ] Criterion 2
|
||||||
|
- [ ] Criterion 3
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | [Requirement description] | High |
|
||||||
|
| FR-002 | [Requirement description] | Medium |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: [e.g., API response < 200ms]
|
||||||
|
- Security: [e.g., Role-based access control]
|
||||||
|
- Compatibility: [e.g., Works on mobile and desktop]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Architecture Diagram
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: [List controllers, services, repositories]
|
||||||
|
- **Frontend**: [List components, hooks, stores]
|
||||||
|
- **Database**: [List tables, changes needed]
|
||||||
|
- **External Services**: [List any third-party services]
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
1. User action → Frontend → API call
|
||||||
|
2. API endpoint → Application service → Domain logic
|
||||||
|
3. Repository → Database
|
||||||
|
4. Return response → Frontend update
|
||||||
|
|
||||||
|
### API Changes
|
||||||
|
| Endpoint | Method | Description |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/api/new-endpoint` | POST | [Description] |
|
||||||
|
|
||||||
|
### Database Changes
|
||||||
|
```sql
|
||||||
|
-- SQL schema changes if applicable
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Setup & Foundation
|
||||||
|
- [ ] Task 1
|
||||||
|
- [ ] Task 2
|
||||||
|
|
||||||
|
### Phase 2: Core Implementation
|
||||||
|
- [ ] Task 3
|
||||||
|
- [ ] Task 4
|
||||||
|
|
||||||
|
### Phase 3: Testing & Polish
|
||||||
|
- [ ] Write unit tests
|
||||||
|
- [ ] Write integration tests
|
||||||
|
- [ ] Manual testing
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Design Complete | [Date] | ⏳ |
|
||||||
|
| Backend Complete | [Date] | ⏳ |
|
||||||
|
| Frontend Complete | [Date] | ⏳ |
|
||||||
|
| Testing Complete | [Date] | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Create domain entity/models
|
||||||
|
- [ ] Create repository interface
|
||||||
|
- [ ] Implement repository
|
||||||
|
- [ ] Create application service
|
||||||
|
- [ ] Create API endpoints
|
||||||
|
- [ ] Add validation
|
||||||
|
- [ ] Write unit tests
|
||||||
|
- [ ] Write integration tests
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] Create components
|
||||||
|
- [ ] Add state management
|
||||||
|
- [ ] Create hooks
|
||||||
|
- [ ] Add API client calls
|
||||||
|
- [ ] Implement UI/UX
|
||||||
|
- [ ] Write component tests
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Update schema
|
||||||
|
- [ ] Create migrations
|
||||||
|
- [ ] Seed data (if needed)
|
||||||
|
|
||||||
|
### DevOps
|
||||||
|
- [ ] Update CI/CD pipeline
|
||||||
|
- [ ] Update deployment scripts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Feature A](feature-a.md) - Required for authentication
|
||||||
|
- [Feature B](feature-b.md) - Provides shared components
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Library/Package: Version - Purpose
|
||||||
|
- External API: Documentation link
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Blocker 1 - Description
|
||||||
|
- [ ] Blocker 2 - Description
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| [Date] | [Decision] | [Why this approach] |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Note 1: [Important implementation detail]
|
||||||
|
- Note 2: [Workaround for limitation]
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ [Potential pitfall and how to avoid it]
|
||||||
|
|
||||||
|
### Lessons Learned
|
||||||
|
- [What you learned during implementation]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| [Date] | Created | Initial plan |
|
||||||
|
| [Date] | In Progress | Started development |
|
||||||
|
| [Date] | Code Review | PR submitted |
|
||||||
|
| [Date] | Completed | Feature deployed |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Backend: [Link to code or describe location]
|
||||||
|
- Frontend: [Link to code or describe location]
|
||||||
|
- Tests: [Link to tests]
|
||||||
|
- PR: [Link to pull request]
|
||||||
|
- Design Mockups: [Link to Figma/design files]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Template last updated: May 31, 2025*
|
||||||
325
docs/features/user-authentication.md
Normal file
325
docs/features/user-authentication.md
Normal file
|
|
@ -0,0 +1,325 @@
|
||||||
|
# Feature: User Authentication & Authorization
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: Medium
|
||||||
|
> **Estimate**: 4-6 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, Lesson Management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement user authentication and authorization system using ASP.NET Core Identity with JWT token-based authentication.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a user, I want to register, login, and access my personalized learning content so that I can track my progress and continue from where I left off.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Users can register with username, email, and password
|
||||||
|
- [ ] Users can login with email and password
|
||||||
|
- [ ] Users receive JWT token upon successful authentication
|
||||||
|
- [ ] JWT token is required for protected API endpoints
|
||||||
|
- [ ] Token expiration and refresh mechanism
|
||||||
|
- [ ] Password hashing for security
|
||||||
|
- [ ] Current user information available via /api/auth/me
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | User registration endpoint | High |
|
||||||
|
| FR-002 | User login endpoint | High |
|
||||||
|
| FR-003 | JWT token generation and validation | High |
|
||||||
|
| FR-004 | Protected routes require authentication | High |
|
||||||
|
| FR-005 | Current user endpoint | Medium |
|
||||||
|
| FR-006 | Password reset functionality | Low |
|
||||||
|
| FR-007 | Email verification (optional for MVP) | Low |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Security: Passwords hashed with bcrypt or similar
|
||||||
|
- Security: JWT tokens expire after 24 hours
|
||||||
|
- Security: Refresh tokens for seamless UX
|
||||||
|
- Performance: Authentication < 500ms
|
||||||
|
- Compatibility: Works with React frontend
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: AuthController, AuthService, JWT configuration
|
||||||
|
- **Database**: Users table (from initial schema)
|
||||||
|
- **Models**: User, LoginDto, RegisterDto, AuthResponse
|
||||||
|
- **Middleware**: JWT authentication middleware
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
User Registration:
|
||||||
|
1. Frontend POST /api/auth/register with {username, email, password}
|
||||||
|
2. Backend validates input
|
||||||
|
3. Backend hashes password
|
||||||
|
4. Backend creates user in database
|
||||||
|
5. Backend generates JWT token
|
||||||
|
6. Returns {userId, token} to frontend
|
||||||
|
|
||||||
|
User Login:
|
||||||
|
1. Frontend POST /api/auth/login with {email, password}
|
||||||
|
2. Backend validates credentials
|
||||||
|
3. Backend generates JWT token
|
||||||
|
4. Returns {userId, token} to frontend
|
||||||
|
|
||||||
|
Protected Endpoint:
|
||||||
|
1. Frontend includes token in Authorization header
|
||||||
|
2. Backend middleware validates token
|
||||||
|
3. Backend processes request if valid
|
||||||
|
4. Returns 401 if token invalid/expired
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
| Endpoint | Method | Description | Auth Required |
|
||||||
|
|----------|--------|-------------|----------------|
|
||||||
|
| `/api/auth/register` | POST | Register new user | No |
|
||||||
|
| `/api/auth/login` | POST | Login existing user | No |
|
||||||
|
| `/api/auth/me` | GET | Get current user info | Yes |
|
||||||
|
| `/api/auth/logout` | POST | Invalidate token | Yes |
|
||||||
|
| `/api/auth/refresh` | POST | Refresh expired token | Yes |
|
||||||
|
|
||||||
|
### Database Schema (from application-plan.md)
|
||||||
|
```sql
|
||||||
|
CREATE TABLE Users (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
Username VARCHAR(50) UNIQUE NOT NULL,
|
||||||
|
Email VARCHAR(100) UNIQUE NOT NULL,
|
||||||
|
PasswordHash VARCHAR(255) NOT NULL,
|
||||||
|
CurrentLevel VARCHAR(10) DEFAULT 'A1',
|
||||||
|
Streak INT DEFAULT 0,
|
||||||
|
TotalPoints INT DEFAULT 0,
|
||||||
|
CreatedAt TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Backend Authentication (3-4 hours)
|
||||||
|
- [ ] Create User model and DTOs (RegisterDto, LoginDto, AuthResponse)
|
||||||
|
- [ ] Configure ASP.NET Core Identity
|
||||||
|
- [ ] Create AuthService with user registration logic
|
||||||
|
- [ ] Create AuthService with user login logic
|
||||||
|
- [ ] Configure JWT token generation
|
||||||
|
- [ ] Create AuthController with endpoints
|
||||||
|
- [ ] Add JWT authentication middleware
|
||||||
|
- [ ] Configure CORS for frontend
|
||||||
|
|
||||||
|
### Phase 2: Database Integration (1-2 hours)
|
||||||
|
- [ ] Update User entity to match schema
|
||||||
|
- [ ] Configure EF Core user repository
|
||||||
|
- [ ] Implement password hashing
|
||||||
|
- [ ] Create user seed data (admin user)
|
||||||
|
- [ ] Test database operations
|
||||||
|
|
||||||
|
### Phase 3: Token Management (1 hour)
|
||||||
|
- [ ] Configure JWT settings in appsettings.json
|
||||||
|
- [ ] Implement token validation middleware
|
||||||
|
- [ ] Add token refresh mechanism
|
||||||
|
- [ ] Set up token expiration (24 hours)
|
||||||
|
- [ ] Configure refresh token rotation
|
||||||
|
|
||||||
|
### Phase 4: Frontend Integration (Optional - if doing full stack)
|
||||||
|
- [ ] Create auth service in React
|
||||||
|
- [ ] Implement login/registration forms
|
||||||
|
- [ ] Store token in localStorage/cookies
|
||||||
|
- [ ] Add auth headers to API requests
|
||||||
|
- [ ] Handle token expiration
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Backend Auth Complete | - | ⏳ |
|
||||||
|
| Database Integration | - | ⏳ |
|
||||||
|
| Token Management | - | ⏳ |
|
||||||
|
| Frontend Integration | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Create Models/User.cs with properties
|
||||||
|
- [ ] Create DTOs/Auth/RegisterDto.cs
|
||||||
|
- [ ] Create DTOs/Auth/LoginDto.cs
|
||||||
|
- [ ] Create DTOs/Auth/AuthResponse.cs
|
||||||
|
- [ ] Create Services/AuthService.cs
|
||||||
|
- [ ] Create Controllers/AuthController.cs
|
||||||
|
- [ ] Configure JWT in Program.cs
|
||||||
|
- [ ] Add [Authorize] attribute to protected endpoints
|
||||||
|
- [ ] Create AuthMiddleware.cs
|
||||||
|
- [ ] Configure CORS policy
|
||||||
|
- [ ] Write unit tests for AuthService
|
||||||
|
- [ ] Write integration tests for AuthController
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Update User entity mapping
|
||||||
|
- [ ] Create UserRepository
|
||||||
|
- [ ] Implement password hashing
|
||||||
|
- [ ] Create migration for Users table
|
||||||
|
- [ ] Seed admin user
|
||||||
|
|
||||||
|
### Token Management
|
||||||
|
- [ ] Configure JWT settings
|
||||||
|
- [ ] Implement token generation
|
||||||
|
- [ ] Implement token validation
|
||||||
|
- [ ] Implement token refresh
|
||||||
|
- [ ] Set token expiration
|
||||||
|
|
||||||
|
### Frontend (Optional)
|
||||||
|
- [ ] Create authService.ts
|
||||||
|
- [ ] Create LoginPage component
|
||||||
|
- [ ] Create RegisterPage component
|
||||||
|
- [ ] Create AuthContext for user state
|
||||||
|
- [ ] Implement protected route wrapper
|
||||||
|
- [ ] Add logout functionality
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required (backend project and database)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- ASP.NET Core Identity
|
||||||
|
- JWT Bearer Authentication package
|
||||||
|
- BouncyCastle or similar for password hashing
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete first
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Authentication-Specific Criteria
|
||||||
|
- [ ] Users can successfully register with valid credentials
|
||||||
|
- [ ] Users can successfully login with valid credentials
|
||||||
|
- [ ] Invalid credentials are rejected with appropriate error messages
|
||||||
|
- [ ] JWT tokens are generated and validated correctly
|
||||||
|
- [ ] Token expiration works as configured
|
||||||
|
- [ ] Token refresh mechanism works
|
||||||
|
- [ ] Protected endpoints reject requests without valid tokens
|
||||||
|
- [ ] Passwords are hashed and never stored in plain text
|
||||||
|
- [ ] Rate limiting on auth endpoints configured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Authentication-Specific Tests
|
||||||
|
|
||||||
|
#### Backend Tests
|
||||||
|
- [ ] Register with valid data → success
|
||||||
|
- [ ] Register with duplicate email → error
|
||||||
|
- [ ] Register with duplicate username → error
|
||||||
|
- [ ] Register with invalid password → error
|
||||||
|
- [ ] Login with valid credentials → success
|
||||||
|
- [ ] Login with invalid email → error
|
||||||
|
- [ ] Login with invalid password → error
|
||||||
|
- [ ] Login with valid token → success
|
||||||
|
- [ ] Login with expired token → error
|
||||||
|
- [ ] Login with invalid token → error
|
||||||
|
- [ ] Access protected endpoint without token → 401
|
||||||
|
- [ ] Access protected endpoint with valid token → success
|
||||||
|
- [ ] Access protected endpoint with invalid token → 401
|
||||||
|
- [ ] Token refresh → new valid token
|
||||||
|
- [ ] Rate limiting on login attempts → 429 after N attempts
|
||||||
|
|
||||||
|
#### Frontend Tests
|
||||||
|
- [ ] Registration form validation
|
||||||
|
- [ ] Registration form submission
|
||||||
|
- [ ] Login form validation
|
||||||
|
- [ ] Login form submission
|
||||||
|
- [ ] Token storage in localStorage/cookies
|
||||||
|
- [ ] Token inclusion in API requests
|
||||||
|
- [ ] Protected route redirection
|
||||||
|
- [ ] Logout functionality
|
||||||
|
- [ ] Session expiration handling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Use JWT over cookies | Stateless, works well with SPAs, scalable |
|
||||||
|
| May 31, 2025 | ASP.NET Core Identity | Built-in, well-tested, integrates with EF Core |
|
||||||
|
| May 31, 2025 | 24-hour token expiration | Balance between security and UX |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Store only password hash, never plain text
|
||||||
|
- Use HttpOnly cookies for refresh tokens if possible
|
||||||
|
- Sanitize username/email inputs to prevent injection
|
||||||
|
- Rate limit login attempts to prevent brute force
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ JWT secret must be long and random (>32 characters)
|
||||||
|
- ⚠️ Token must be stored securely on frontend (HttpOnly cookie or secure localStorage)
|
||||||
|
- ⚠️ CORS must be configured to accept credentials if using cookies
|
||||||
|
- ⚠️ Password hashing should use work factor appropriate for your hardware
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Application Plan: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Reference: [ASP.NET Core Identity Docs](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity)
|
||||||
|
- Reference: [JWT in .NET](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/jwt/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
368
docs/features/vocabulary-system.md
Normal file
368
docs/features/vocabulary-system.md
Normal file
|
|
@ -0,0 +1,368 @@
|
||||||
|
# Feature: Vocabulary System
|
||||||
|
|
||||||
|
> **Status**: ⏳ Planned
|
||||||
|
> **Priority**: High
|
||||||
|
> **Complexity**: High
|
||||||
|
> **Estimate**: 8-12 hours
|
||||||
|
> **Assignee**: -
|
||||||
|
> **Created**: May 31, 2025
|
||||||
|
> **Target Completion**: -
|
||||||
|
> **PR**: -
|
||||||
|
> **Related Features**: Infrastructure Setup, Lesson Management, AI Services (TTS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 Overview
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Implement a comprehensive vocabulary management system that includes word storage, retrieval, audio generation, and integration with lessons.
|
||||||
|
|
||||||
|
### User Story
|
||||||
|
As a learner, I want to study German vocabulary with translations, articles (der/die/das), and audio pronunciations so that I can build my word knowledge effectively.
|
||||||
|
|
||||||
|
### Acceptance Criteria
|
||||||
|
- [ ] Vocabulary words can be created, read, updated, and deleted (Admin)
|
||||||
|
- [ ] Each word has: German text, English translation, article (optional), audio URL
|
||||||
|
- [ ] Vocabulary is associated with specific lessons
|
||||||
|
- [ ] Words can be filtered by lesson, level, or source (Goethe/DW)
|
||||||
|
- [ ] Audio is generated for each word using Coqui TTS
|
||||||
|
- [ ] Users can practice vocabulary through various exercises
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Requirements
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
| ID | Requirement | Priority |
|
||||||
|
|----|-------------|----------|
|
||||||
|
| FR-001 | CRUD operations for vocabulary words | High |
|
||||||
|
| FR-002 | Associate words with lessons | High |
|
||||||
|
| FR-003 | Store article information (der/die/das) | High |
|
||||||
|
| FR-004 | Generate audio for each word | High |
|
||||||
|
| FR-005 | Import vocabulary from Goethe Institut | High |
|
||||||
|
| FR-006 | Import vocabulary from DW Learn German | High |
|
||||||
|
| FR-007 | Filter vocabulary by lesson/level/source | Medium |
|
||||||
|
| FR-008 | Vocabulary exercises (flashcards, matching) | Medium |
|
||||||
|
| FR-009 | Admin bulk import functionality | Medium |
|
||||||
|
|
||||||
|
### Non-Functional Requirements
|
||||||
|
- Performance: Vocabulary listing < 100ms
|
||||||
|
- Storage: Audio files ~50-100KB per word
|
||||||
|
- Security: Only admins can create/edit/delete words
|
||||||
|
- Data Integrity: Word-article combinations must be valid
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Technical Design
|
||||||
|
|
||||||
|
### Components Involved
|
||||||
|
- **Backend**: VocabularyController, VocabularyService, VocabularyImportService
|
||||||
|
- **Database**: Vocabulary table
|
||||||
|
- **Models**: Vocabulary, VocabularyDto
|
||||||
|
- **External**: Coqui TTS for audio generation
|
||||||
|
- **Frontend**: VocabularyTab, VocabularyCard, VocabularyExercise components
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
```
|
||||||
|
1. Admin imports vocabulary from Goethe/DW
|
||||||
|
2. System scrapes word list from source
|
||||||
|
3. For each word:
|
||||||
|
a. Store in Vocabulary table
|
||||||
|
b. Generate audio using Coqui TTS
|
||||||
|
c. Save audio file and update AudioUrl
|
||||||
|
4. User views lesson vocabulary
|
||||||
|
5. Frontend displays words with audio playback
|
||||||
|
6. User can click to hear pronunciation
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
| Endpoint | Method | Description | Auth Required |
|
||||||
|
|----------|--------|-------------|----------------|
|
||||||
|
| `/api/vocabulary` | GET | List all vocabulary (with filters) | Yes |
|
||||||
|
| `/api/vocabulary/{id}` | GET | Get specific vocabulary word | Yes |
|
||||||
|
| `/api/vocabulary` | POST | Create new vocabulary word (Admin) | Yes |
|
||||||
|
| `/api/vocabulary/{id}` | PUT | Update vocabulary word (Admin) | Yes |
|
||||||
|
| `/api/vocabulary/{id}` | DELETE | Delete vocabulary word (Admin) | Yes |
|
||||||
|
| `/api/vocabulary/lesson/{lessonId}` | GET | Get vocabulary for a lesson | Yes |
|
||||||
|
| `/api/vocabulary/import` | POST | Import from Goethe/DW (Admin) | Yes |
|
||||||
|
| `/api/vocabulary/audio/{id}` | GET | Get audio file for word | Yes |
|
||||||
|
|
||||||
|
### Database Schema (from application-plan.md)
|
||||||
|
```sql
|
||||||
|
CREATE TABLE Vocabulary (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
LessonId INT REFERENCES Lessons(Id) ON DELETE CASCADE,
|
||||||
|
Word VARCHAR(50) NOT NULL,
|
||||||
|
Translation VARCHAR(100) NOT NULL,
|
||||||
|
Article VARCHAR(10) CHECK (Article IN ('der', 'die', 'das', '')),
|
||||||
|
AudioUrl VARCHAR(255),
|
||||||
|
ImageUrl VARCHAR(255),
|
||||||
|
Source VARCHAR(50) CHECK (Source IN ('Goethe', 'DW'))
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vocabulary Word Structure
|
||||||
|
```csharp
|
||||||
|
public class Vocabulary
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int LessonId { get; set; }
|
||||||
|
public string Word { get; set; } // e.g., "Buch"
|
||||||
|
public string Translation { get; set; } // e.g., "book"
|
||||||
|
public string? Article { get; set; } // "der", "die", "das", or null
|
||||||
|
public string? AudioUrl { get; set; } // URL to audio file
|
||||||
|
public string? ImageUrl { get; set; } // Optional image URL
|
||||||
|
public string Source { get; set; } // "Goethe" or "DW"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Implementation Plan
|
||||||
|
|
||||||
|
### Phase 1: Database & Models (2 hours)
|
||||||
|
- [ ] Create Vocabulary entity
|
||||||
|
- [ ] Create VocabularyDto for API responses
|
||||||
|
- [ ] Create VocabularyRepository interface
|
||||||
|
- [ ] Create VocabularyRepository implementation
|
||||||
|
- [ ] Create migration for Vocabulary table
|
||||||
|
- [ ] Add vocabulary to Lesson entity (one-to-many relationship)
|
||||||
|
|
||||||
|
### Phase 2: Core CRUD Operations (2-3 hours)
|
||||||
|
- [ ] Create VocabularyService with basic CRUD
|
||||||
|
- [ ] Create VocabularyController
|
||||||
|
- [ ] Implement filtering (by lesson, level, source)
|
||||||
|
- [ ] Add validation for word data
|
||||||
|
- [ ] Add authorization (Admin for write operations)
|
||||||
|
- [ ] Write unit tests for VocabularyService
|
||||||
|
|
||||||
|
### Phase 3: Audio Generation (2-3 hours)
|
||||||
|
- [ ] Integrate with Coqui TTS service
|
||||||
|
- [ ] Create audio generation queue/background job
|
||||||
|
- [ ] Configure audio storage location
|
||||||
|
- [ ] Implement audio file serving endpoint
|
||||||
|
- [ ] Add audio URL to vocabulary DTOs
|
||||||
|
- [ ] Create migration to add AudioUrl column
|
||||||
|
|
||||||
|
### Phase 4: Vocabulary Import (2-3 hours)
|
||||||
|
- [ ] Create VocabularyImportService
|
||||||
|
- [ ] Implement Goethe Institut scraper
|
||||||
|
- [ ] Implement DW Learn German scraper
|
||||||
|
- [ ] Create bulk import endpoint
|
||||||
|
- [ ] Add validation for imported words
|
||||||
|
- [ ] Generate audio for imported words
|
||||||
|
- [ ] Create admin UI for import (optional)
|
||||||
|
|
||||||
|
### Phase 5: Frontend Integration (1-2 hours)
|
||||||
|
- [ ] Create VocabularyTab component
|
||||||
|
- [ ] Create VocabularyCard component with audio playback
|
||||||
|
- [ ] Create VocabularyExercise component
|
||||||
|
- [ ] Add vocabulary to LessonPage
|
||||||
|
|
||||||
|
### Milestones
|
||||||
|
| Milestone | Date | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Database & Models | - | ⏳ |
|
||||||
|
| Core CRUD | - | ⏳ |
|
||||||
|
| Audio Generation | - | ⏳ |
|
||||||
|
| Vocabulary Import | - | ⏳ |
|
||||||
|
| Frontend Integration | - | ⏳ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Tasks
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- [ ] Create Domain/Entities/Vocabulary.cs
|
||||||
|
- [ ] Create Application/DTOs/VocabularyDto.cs
|
||||||
|
- [ ] Create Domain/Interfaces/IVocabularyRepository.cs
|
||||||
|
- [ ] Create Infrastructure/Data/Repositories/VocabularyRepository.cs
|
||||||
|
- [ ] Update Lesson entity to include Vocabulary collection
|
||||||
|
- [ ] Create Application/Services/VocabularyService.cs
|
||||||
|
- [ ] Create Presentation/Controllers/VocabularyController.cs
|
||||||
|
- [ ] Create VocabularyImportService
|
||||||
|
- [ ] Create endpoints for audio serving
|
||||||
|
- [ ] Integrate with Coqui TTS service
|
||||||
|
- [ ] Register services in Program.cs
|
||||||
|
- [ ] Write unit tests
|
||||||
|
- [ ] Write integration tests
|
||||||
|
|
||||||
|
### Database
|
||||||
|
- [ ] Create migration for Vocabulary table
|
||||||
|
- [ ] Add foreign key to Lessons table
|
||||||
|
- [ ] Add indexes for LessonId, Source
|
||||||
|
- [ ] Apply migration
|
||||||
|
|
||||||
|
### Audio Generation
|
||||||
|
- [ ] Set up Coqui TTS configuration
|
||||||
|
- [ ] Create audio file storage directory
|
||||||
|
- [ ] Implement audio generation for new words
|
||||||
|
- [ ] Implement background job for bulk audio generation
|
||||||
|
- [ ] Create audio file cleanup mechanism
|
||||||
|
|
||||||
|
### Vocabulary Import
|
||||||
|
- [ ] Research Goethe Institut vocabulary structure
|
||||||
|
- [ ] Research DW Learn German vocabulary structure
|
||||||
|
- [ ] Implement web scraping for Goethe
|
||||||
|
- [ ] Implement web scraping for DW
|
||||||
|
- [ ] Create bulk import API endpoint
|
||||||
|
- [ ] Add rate limiting to scrapers
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- [ ] Create components/VocabularyTab.tsx
|
||||||
|
- [ ] Create components/VocabularyCard.tsx
|
||||||
|
- [ ] Create components/VocabularyExercise.tsx
|
||||||
|
- [ ] Create hooks/useVocabulary.ts
|
||||||
|
- [ ] Integrate with LessonPage
|
||||||
|
- [ ] Add audio playback functionality
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Dependencies
|
||||||
|
|
||||||
|
### Feature Dependencies
|
||||||
|
- [Infrastructure Setup](infrastructure-setup.md) - Required
|
||||||
|
- [Lesson Management](lesson-management.md) - Required (vocabulary associated with lessons)
|
||||||
|
- [AI Services - TTS](ai-services.md) - Required (for audio generation)
|
||||||
|
|
||||||
|
### Technical Dependencies
|
||||||
|
- Coqui TTS Python library
|
||||||
|
- HTML Agility Pack or similar for web scraping
|
||||||
|
- AutoMapper (optional)
|
||||||
|
|
||||||
|
### Blockers
|
||||||
|
- [ ] Infrastructure Setup must be complete
|
||||||
|
- [ ] Lesson Management must be complete for vocabulary-lesson association
|
||||||
|
- [ ] Coqui TTS service must be configured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Definition of Done
|
||||||
|
|
||||||
|
### General Criteria (All Features)
|
||||||
|
- [ ] All acceptance criteria met and verified
|
||||||
|
- [ ] All tasks in this document completed
|
||||||
|
- [ ] Code follows Clean Architecture principles
|
||||||
|
- [ ] Code reviewed and approved by at least 1 team member
|
||||||
|
- [ ] All tests passing (unit, integration)
|
||||||
|
- [ ] Documentation updated (README, AGENTS.md if applicable)
|
||||||
|
- [ ] Feature works in development environment
|
||||||
|
- [ ] Feature deployed to staging environment
|
||||||
|
- [ ] Performance meets defined targets
|
||||||
|
- [ ] Security review completed
|
||||||
|
- [ ] No critical bugs or blockers
|
||||||
|
|
||||||
|
### Vocabulary-Specific Criteria
|
||||||
|
- [ ] Vocabulary words can be created, read, updated, and deleted
|
||||||
|
- [ ] Each word has: German text, translation, article, audio URL
|
||||||
|
- [ ] Words are correctly associated with lessons
|
||||||
|
- [ ] Words can be filtered by lesson, level, source
|
||||||
|
- [ ] Audio is generated for all vocabulary words
|
||||||
|
- [ ] Audio files are accessible and playable
|
||||||
|
- [ ] Goethe Institut vocabulary import works
|
||||||
|
- [ ] DW Learn German vocabulary import works
|
||||||
|
- [ ] Vocabulary exercises (flashcards, matching) are functional
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Testing Strategy
|
||||||
|
|
||||||
|
### Testing Approach
|
||||||
|
|
||||||
|
| Test Type | Coverage | Tools | Responsibility |
|
||||||
|
|-----------|----------|-------|----------------|
|
||||||
|
| Unit Tests | 80%+ code coverage | MsTest, Moq | Backend Dev |
|
||||||
|
| Integration Tests | All service interactions | MsTest, TestContainers | Backend Dev |
|
||||||
|
| API Tests | All endpoints | MsTest, HttpClient | Backend Dev |
|
||||||
|
| Frontend Unit Tests | Component logic | Vitest | Frontend Dev |
|
||||||
|
| Frontend Integration | Service integration | Vitest | Frontend Dev |
|
||||||
|
| E2E Tests | Critical user journeys | Playwright | QA/Dev |
|
||||||
|
| Manual Testing | Exploratory, edge cases | BrowserStack | QA |
|
||||||
|
|
||||||
|
### Vocabulary-Specific Tests
|
||||||
|
|
||||||
|
#### Backend Tests
|
||||||
|
- [ ] Create word with valid data → success
|
||||||
|
- [ ] Create word with missing required fields → error
|
||||||
|
- [ ] Create word with invalid article → error
|
||||||
|
- [ ] Create word with invalid source → error
|
||||||
|
- [ ] Get word by ID → returns correct word
|
||||||
|
- [ ] Get words by lesson → returns correct list
|
||||||
|
- [ ] Get words by level → returns correct list
|
||||||
|
- [ ] Get words by source → returns correct list
|
||||||
|
- [ ] Update word → success
|
||||||
|
- [ ] Update word with invalid data → error
|
||||||
|
- [ ] Delete word → success
|
||||||
|
- [ ] Bulk import from Goethe → creates words correctly
|
||||||
|
- [ ] Bulk import from DW → creates words correctly
|
||||||
|
- [ ] Audio generation for word → creates audio file
|
||||||
|
|
||||||
|
#### Audio Tests
|
||||||
|
- [ ] Audio file generated for new word
|
||||||
|
- [ ] Audio file accessible via endpoint
|
||||||
|
- [ ] Audio file is valid WAV format
|
||||||
|
- [ ] Audio file quality is acceptable
|
||||||
|
- [ ] Audio file size is within limits
|
||||||
|
|
||||||
|
#### Integration Tests
|
||||||
|
- [ ] Create lesson with vocabulary → both created
|
||||||
|
- [ ] Get lesson → includes vocabulary
|
||||||
|
- [ ] Delete lesson → cascades to vocabulary
|
||||||
|
- [ ] Import vocabulary → audio generated for all words
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Notes & Decisions
|
||||||
|
|
||||||
|
### Decisions Made
|
||||||
|
| Date | Decision | Rationale |
|
||||||
|
|------|----------|-----------|
|
||||||
|
| May 31, 2025 | Generate audio for all vocabulary | Essential for pronunciation practice |
|
||||||
|
| May 31, 2025 | Store audio files on filesystem | Simple for MVP, can migrate to CDN later |
|
||||||
|
| May 31, 2025 | Import from Goethe and DW | High-quality, trusted sources |
|
||||||
|
| May 31, 2025 | Include article information | Critical for German language learning |
|
||||||
|
|
||||||
|
### Technical Notes
|
||||||
|
- Audio files should be stored with consistent naming: `/audio/vocabulary/{id}.wav`
|
||||||
|
- Vocabulary table has CHECK constraint for Article (only der/die/das or empty)
|
||||||
|
- Vocabulary table has CHECK constraint for Source (only Goethe or DW)
|
||||||
|
- Consider adding phonetic transcription (IPA) in the future
|
||||||
|
- Audio generation can be resource-intensive - consider queueing for bulk operations
|
||||||
|
|
||||||
|
### Gotchas
|
||||||
|
- ⚠️ Coqui TTS may have issues with some German words - need fallback mechanism
|
||||||
|
- ⚠️ Web scraping may break if Goethe/DW change their HTML structure
|
||||||
|
- ⚠️ Audio files can be large - consider compression
|
||||||
|
- ⚠️ Need to handle duplicate words across different lessons
|
||||||
|
- ⚠️ Article may be empty for verbs, adjectives, etc.
|
||||||
|
|
||||||
|
### Article Rules Reference
|
||||||
|
- **der**: Masculine nouns (e.g., der Mann, der Tag)
|
||||||
|
- **die**: Feminine nouns (e.g., die Frau, die Stadt)
|
||||||
|
- **das**: Neuter nouns (e.g., das Kind, das Haus)
|
||||||
|
- **empty**: Verbs (e.g., gehen, sein), adjectives, adverbs, prepositions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Progress History
|
||||||
|
|
||||||
|
| Date | Status Change | Notes |
|
||||||
|
|------|---------------|-------|
|
||||||
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Related Files & Links
|
||||||
|
|
||||||
|
- Architecture: [Backend Structure](../architecture/backend-structure.md)
|
||||||
|
- Architecture: [Application Plan](../architecture/application-plan.md)
|
||||||
|
- Database Schema: [Initial Database Schema](../database/initial-database-schema.sql)
|
||||||
|
- Feature: [Lesson Management](lesson-management.md)
|
||||||
|
- Feature: [AI Services](ai-services.md)
|
||||||
|
- Reference: [Goethe Institut Vocabulary](https://www.goethe.de/en/spr/ueb.html)
|
||||||
|
- Reference: [DW Learn German Vocabulary](https://learngerman.dw.com/en/learn-german/s-9528)
|
||||||
|
- Reference: [Coqui TTS](https://github.com/coqui-ai/TTS)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Feature created from application-plan.md*
|
||||||
24
german-app-frontend/.gitignore
vendored
Normal file
24
german-app-frontend/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
73
german-app-frontend/README.md
Normal file
73
german-app-frontend/README.md
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
# React + TypeScript + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
|
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
|
||||||
|
|
||||||
|
## React Compiler
|
||||||
|
|
||||||
|
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||||
|
|
||||||
|
## Expanding the ESLint configuration
|
||||||
|
|
||||||
|
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
// Other configs...
|
||||||
|
|
||||||
|
// Remove tseslint.configs.recommended and replace with this
|
||||||
|
tseslint.configs.recommendedTypeChecked,
|
||||||
|
// Alternatively, use this for stricter rules
|
||||||
|
tseslint.configs.strictTypeChecked,
|
||||||
|
// Optionally, add this for stylistic rules
|
||||||
|
tseslint.configs.stylisticTypeChecked,
|
||||||
|
|
||||||
|
// Other configs...
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
},
|
||||||
|
// other options...
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// eslint.config.js
|
||||||
|
import reactX from 'eslint-plugin-react-x'
|
||||||
|
import reactDom from 'eslint-plugin-react-dom'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
// Other configs...
|
||||||
|
// Enable lint rules for React
|
||||||
|
reactX.configs['recommended-typescript'],
|
||||||
|
// Enable lint rules for React DOM
|
||||||
|
reactDom.configs.recommended,
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
},
|
||||||
|
// other options...
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
```
|
||||||
22
german-app-frontend/eslint.config.js
Normal file
22
german-app-frontend/eslint.config.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import js from '@eslint/js'
|
||||||
|
import globals from 'globals'
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
js.configs.recommended,
|
||||||
|
tseslint.configs.recommended,
|
||||||
|
reactHooks.configs.flat.recommended,
|
||||||
|
reactRefresh.configs.vite,
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
globals: globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
13
german-app-frontend/index.html
Normal file
13
german-app-frontend/index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>german-app-frontend</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2768
german-app-frontend/package-lock.json
generated
Normal file
2768
german-app-frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
30
german-app-frontend/package.json
Normal file
30
german-app-frontend/package.json
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "german-app-frontend",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^19.2.6",
|
||||||
|
"react-dom": "^19.2.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^10.0.1",
|
||||||
|
"@types/node": "^24.12.3",
|
||||||
|
"@types/react": "^19.2.14",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
|
"eslint": "^10.3.0",
|
||||||
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.5.2",
|
||||||
|
"globals": "^17.6.0",
|
||||||
|
"typescript": "~6.0.2",
|
||||||
|
"typescript-eslint": "^8.59.2",
|
||||||
|
"vite": "^8.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
german-app-frontend/public/favicon.svg
Normal file
1
german-app-frontend/public/favicon.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 9.3 KiB |
24
german-app-frontend/public/icons.svg
Normal file
24
german-app-frontend/public/icons.svg
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
||||||
|
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
||||||
|
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="discord-icon" viewBox="0 0 20 19">
|
||||||
|
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="github-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="social-icon" viewBox="0 0 20 20">
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
||||||
|
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
||||||
|
</symbol>
|
||||||
|
<symbol id="x-icon" viewBox="0 0 19 19">
|
||||||
|
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
||||||
|
</symbol>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.9 KiB |
25
german-app-frontend/tsconfig.app.json
Normal file
25
german-app-frontend/tsconfig.app.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"target": "es2023",
|
||||||
|
"lib": ["ES2023", "DOM"],
|
||||||
|
"module": "esnext",
|
||||||
|
"types": ["vite/client"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
7
german-app-frontend/tsconfig.json
Normal file
7
german-app-frontend/tsconfig.json
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
24
german-app-frontend/tsconfig.node.json
Normal file
24
german-app-frontend/tsconfig.node.json
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "es2023",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "esnext",
|
||||||
|
"types": ["node"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
7
german-app-frontend/vite.config.ts
Normal file
7
german-app-frontend/vite.config.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
})
|
||||||
Loading…
Add table
Reference in a new issue