📝 docs: add comprehensive user management ADR and technical documentation\n\nAdded ADR-0018 for User Management and Authentication System with:\n- Non-persisted admin user with master password authentication\n- JWT-based authentication with bcrypt password hashing\n- PostgreSQL database schema and GORM integration\n- Admin-assisted password reset workflow\n- Comprehensive security considerations\n\nAdded ADR-0019 for BDD Feature Structure:\n- Epic/User Story organization pattern\n- Unified development workflow\n- Source of truth hierarchy\n\nAdded technical documentation:\n- Complete user management system specification\n- API endpoints and integration details\n- Security architecture and best practices\n\nGenerated by Mistral Vibe.\nCo-Authored-By: Mistral Vibe <vibe@mistral.ai>
Some checks failed
CI/CD Pipeline / CI Pipeline (push) Has been cancelled

This commit is contained in:
2026-04-06 22:41:17 +02:00
parent ed8814a7ce
commit 10c909581c
16 changed files with 1932 additions and 1309 deletions

View File

@@ -238,6 +238,9 @@ main() {
create-issue) cmd_create_issue "$@" ;;
show-issue) cmd_show_issue "$@" ;;
comment-issue) cmd_comment_issue "$@" ;;
list-wiki) cmd_list_wiki "$@" ;;
create-wiki) cmd_create_wiki "$@" ;;
get-wiki) cmd_get_wiki "$@" ;;
*)
echo "Usage: $0 <command> [args...]" >&2
echo "" >&2
@@ -254,6 +257,9 @@ main() {
echo " create-issue <owner> <repo> <title> <description>" >&2
echo " show-issue <owner> <repo> <issue_number>" >&2
echo " comment-issue <owner> <repo> <issue_number> <comment>" >&2
echo " list-wiki <owner> <repo>" >&2
echo " create-wiki <owner> <repo> <title> <content> [message]" >&2
echo " get-wiki <owner> <repo> <page_name>" >&2
exit 1
;;
esac
@@ -330,4 +336,57 @@ cmd_comment_issue() {
api_request "POST" "$endpoint" "$data"
}
# List wiki pages
cmd_list_wiki() {
local owner="$1"
local repo="$2"
if [[ -z "$owner" || -z "$repo" ]]; then
echo "Usage: $0 list-wiki <owner> <repo>" >&2
exit 1
fi
local endpoint="/repos/$owner/$repo/wiki/pages"
api_request "GET" "$endpoint"
}
# Create wiki page
cmd_create_wiki() {
local owner="$1"
local repo="$2"
local title="$3"
local content="$4"
local message="${5:-Initial creation}"
if [[ -z "$owner" || -z "$repo" || -z "$title" || -z "$content" ]]; then
echo "Usage: $0 create-wiki <owner> <repo> <title> <content> [message]" >&2
exit 1
fi
local content_b64=$(echo "$content" | base64)
local endpoint="/repos/$owner/$repo/wiki/new"
local data=$(jq -n --arg title "$title" --arg content "$content_b64" --arg msg "$message" '{
title: $title,
content_base64: $content,
message: $msg
}')
api_request "POST" "$endpoint" "$data"
}
# Get wiki page
cmd_get_wiki() {
local owner="$1"
local repo="$2"
local page_name="$3"
if [[ -z "$owner" || -z "$repo" || -z "$page_name" ]]; then
echo "Usage: $0 get-wiki <owner> <repo> <page_name>" >&2
exit 1
fi
local endpoint="/repos/$owner/$repo/wiki/page/$page_name"
api_request "GET" "$endpoint"
}
main "$@"

View File

@@ -0,0 +1,460 @@
# User Story Implementation Workflow
## 🎯 Overview
This document describes the standardized workflow for implementing user stories in the DanceLessonsCoach project. The workflow follows a test-driven development approach with clear phases and deliverables.
## 🔄 Workflow Diagram
```mermaid
graph TD
A[Product Owner Creates User Story] --> B[Create BDD Test Scenario]
B --> C[BDD Test Fails (Red Phase)]
C --> D[Implement Service with Mocks]
D --> E[Write Unit Tests]
E --> F[Add Real Persistence Layer]
F --> G[BDD Test Passes (Green Phase)]
G --> H[Update OpenAPI Documentation]
H --> I[CI/CD Pipeline Validation]
I --> J[Product Owner Review]
J --> K[Ready for Deployment]
```
## 📋 Detailed Workflow Steps
### Step 1: User Story Creation (Product Owner)
**Responsibility:** Product Owner
**Output:** Gitea issue with clear acceptance criteria
```markdown
## User Story: [Title]
**As a** [role]
**I want to** [feature]
**So that** [benefit]
### Acceptance Criteria
- [ ] Criteria 1
- [ ] Criteria 2
- [ ] Criteria 3
### Technical Notes
- API endpoint: `POST /api/v1/[resource]`
- Database: Requires `users` table
- Security: JWT authentication required
### Priority
- High/Medium/Low
### Estimated Effort
- Story Points: [1-8]
- Complexity: [Low/Medium/High]
```
### Step 2: Create BDD Test Scenario
**Responsibility:** Developer
**Output:** Failing BDD test in `.feature` file
```gherkin
# features/[feature].feature
Feature: [Feature Name]
[Feature description]
@wip @user-management
Scenario: [Scenario Name]
Given [precondition]
When [action]
Then [expected result]
And [additional verification]
```
**Example:**
```gherkin
# features/user-persistence.feature
Feature: User Persistence
Users should be able to register and persist their data
@wip @user-management
Scenario: User registration with persistence
Given the server is running with database
When I register a new user with username "testuser" and password "secure123"
Then the response should contain a user ID
And the user should be persisted in the database
And I should be able to login with the same credentials
```
### Step 3: BDD Test Fails (Red Phase)
**Responsibility:** Developer
**Output:** Failing test execution
```bash
# Run BDD tests
cd /Users/gabrielradureau/Work/Vibe/DanceLessonsCoach
godog features/user-persistence.feature
# Expected: Test fails with "pending" or "undefined" steps
```
### Step 4: Implement Service with Mocks
**Responsibility:** Developer
**Output:** Service implementation with mock persistence
```go
// pkg/user/service.go
package user
type UserService struct {
repo UserRepository
}
func NewUserService(repo UserRepository) *UserService {
return &UserService{repo: repo}
}
func (s *UserService) Register(ctx context.Context, username, password string) (*User, error) {
// Validate input
if err := validateUsername(username); err != nil {
return nil, err
}
// Hash password
hashedPassword, err := hashPassword(password)
if err != nil {
return nil, err
}
// Create user
user := &User{
Username: username,
PasswordHash: hashedPassword,
}
// Persist user (using interface - mockable)
if err := s.repo.CreateUser(user); err != nil {
return nil, err
}
return user, nil
}
```
### Step 5: Write Unit Tests
**Responsibility:** Developer
**Output:** Passing unit tests with mock repository
```go
// pkg/user/service_test.go
package user
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type MockUserRepository struct {
mock.Mock
}
func (m *MockUserRepository) CreateUser(user *User) error {
args := m.Called(user)
return args.Error(0)
}
func TestUserService_Register(t *testing.T) {
// Setup
mockRepo := new(MockUserRepository)
service := NewUserService(mockRepo)
// Expectations
mockRepo.On("CreateUser", mock.AnythingOfType("*user.User")).Return(nil)
// Test
user, err := service.Register(context.Background(), "testuser", "secure123")
// Assertions
assert.NoError(t, err)
assert.NotNil(t, user)
assert.Equal(t, "testuser", user.Username)
mockRepo.AssertExpectations(t)
}
```
### Step 6: Add Real Persistence Layer
**Responsibility:** Developer
**Output:** Database implementation and passing BDD test
```go
// pkg/user/repository.go
package user
import "gorm.io/gorm"
type GormUserRepository struct {
db *gorm.DB
}
func NewGormUserRepository(db *gorm.DB) *GormUserRepository {
return &GormUserRepository{db: db}
}
func (r *GormUserRepository) CreateUser(user *User) error {
return r.db.Create(user).Error
}
func (r *GormUserRepository) GetUserByUsername(username string) (*User, error) {
var user User
err := r.db.Where("username = ?", username).First(&user).Error
return &user, err
}
```
**Database Setup:**
```yaml
# docker-compose.yml
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: dancecoach
POSTGRES_PASSWORD: secure-password
POSTGRES_DB: dance_lessons_coach
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
```
### Step 7: BDD Test Passes (Green Phase)
**Responsibility:** Developer
**Output:** Passing BDD test
```bash
# Run BDD tests with real database
export DLC_DB_HOST=localhost
export DLC_DB_PORT=5432
export DLC_DB_USER=dancecoach
export DLC_DB_PASSWORD=secure-password
export DLC_DB_NAME=dance_lessons_coach
godog features/user-persistence.feature
# Expected: All tests pass
```
### Step 8: Update OpenAPI Documentation
**Responsibility:** Developer
**Output:** Updated Swagger documentation
```go
// pkg/user/api_handlers.go
// Register godoc
// @Summary Register a new user
// @Description Create a new user account
// @Tags API/v1/User
// @Accept json
// @Produce json
// @Param request body RegisterRequest true "User registration data"
// @Success 201 {object} RegisterResponse
// @Failure 400 {object} ErrorResponse
// @Failure 409 {object} ErrorResponse
// @Router /auth/register [post]
func (h *AuthHandler) handleRegister(w http.ResponseWriter, r *http.Request) {
// Implementation
}
// Generate documentation
go generate ./pkg/server/
```
### Step 9: CI/CD Pipeline Validation
**Responsibility:** DevOps/Developer
**Output:** Passing CI/CD pipeline
```yaml
# .gitea/workflows/ci-cd.yaml
jobs:
test:
steps:
- name: Run BDD tests
run: godog features/
- name: Run unit tests
run: go test ./... -cover
- name: Check OpenAPI docs
run: test -f pkg/server/docs/swagger.json
```
### Step 10: Product Owner Review
**Responsibility:** Product Owner
**Output:** Approval or feedback
**Review Checklist:**
- ✅ Acceptance criteria met
- ✅ BDD tests pass
- ✅ Unit tests pass
- ✅ API documentation updated
- ✅ CI/CD pipeline passes
- ✅ Code follows project conventions
- ✅ Security considerations addressed
## 📁 File Structure Example
```
dance-lessons-coach/
├── features/
│ └── user-persistence.feature # BDD tests
├── pkg/
│ └── user/
│ ├── models.go # Data models
│ ├── repository.go # Repository interface
│ ├── gorm_repository.go # GORM implementation
│ ├── service.go # Business logic
│ ├── service_test.go # Unit tests
│ ├── api_handlers.go # HTTP handlers
│ └── context.go # Context utilities
└── docker-compose.yml # Database setup
```
## 🎯 User Story Implementation Example
### User Story: User Registration
**Gitea Issue:**
```markdown
## User Story: User Registration
**As a** new user
**I want to** create an account
**So that** I can access personalized features
### Acceptance Criteria
- ✅ User can register with username and password
- ✅ Username must be unique and 3-50 alphanumeric characters
- ✅ Password must be at least 8 characters
- ✅ User data is persisted in database
- ✅ Successful registration returns user ID and JWT token
- ✅ Duplicate username returns appropriate error
### Technical Implementation
1. Create `features/user-registration.feature` with BDD scenarios
2. Implement `UserService.Register()` method
3. Create `GormUserRepository` for database persistence
4. Add `POST /api/v1/auth/register` endpoint
5. Update OpenAPI documentation
6. Ensure CI/CD tests pass
```
**BDD Test:**
```gherkin
Feature: User Registration
Users should be able to create accounts
@user-registration
Scenario: Successful user registration
Given the server is running with database
When I register with username "newuser" and password "securePassword123"
Then the response status should be 201
And the response should contain "user_id"
And the response should contain "token"
And I should be able to login with username "newuser" and password "securePassword123"
@user-registration
Scenario: Duplicate username registration
Given a user "existinguser" already exists
When I register with username "existinguser" and password "anotherPassword456"
Then the response status should be 409
And the response should contain error "user_exists"
```
**Implementation Steps:**
1. ✅ Create BDD test (failing)
2. ✅ Implement service with mock repository
3. ✅ Write unit tests
4. ✅ Add GORM repository implementation
5. ✅ Update database schema
6. ✅ BDD test passes
7. ✅ Add OpenAPI documentation
8. ✅ CI/CD validation
9. ✅ Product Owner review
## 🔧 Tools and Technologies
- **BDD Testing:** Godog (Cucumber for Go)
- **Mocking:** testify/mock
- **ORM:** GORM with PostgreSQL
- **API Docs:** Swaggo (OpenAPI)
- **CI/CD:** Gitea Actions
- **Testing:** Standard Go testing
## 📈 Metrics and Success Criteria
**User Story Completion:**
- BDD tests: 100% passing
- Unit tests: ≥80% coverage
- Integration tests: All critical paths covered
- Documentation: Complete and accurate
- CI/CD: All checks passing
**Quality Gates:**
- No critical vulnerabilities
- Code review approved
- Performance acceptable
- Error handling comprehensive
- Logging appropriate
## 🎓 Best Practices
### BDD Test Writing
1. **Focus on behavior**, not implementation
2. **One scenario per test** case
3. **Use clear, descriptive** language
4. **Include both happy and error** paths
5. **Keep scenarios independent**
### Service Implementation
1. **Interface-based design** for testability
2. **Context-aware** methods
3. **Proper error handling** and logging
4. **Input validation** at service level
5. **Separation of concerns** between layers
### Repository Pattern
1. **Interface first**, implementation second
2. **Database-agnostic** design
3. **Transaction support** where needed
4. **Efficient queries**
5. **Proper error mapping**
### API Design
1. **RESTful endpoints**
2. **Consistent response** formats
3. **Proper HTTP status** codes
4. **Comprehensive OpenAPI** documentation
5. **Rate limiting** for public endpoints
## 🔄 Feedback Loop
```mermaid
graph LR
PO[Product Owner] -->|Creates User Story| Dev[Developer]
Dev -->|Implements & Tests| CI[CI/CD Pipeline]
CI -->|Pass/Fail| Dev
Dev -->|Ready for Review| PO
PO -->|Approves/Feedback| Dev
Dev -->|Deployed| Prod[Production]
Prod -->|Monitor| PO
```
## 📚 References
- [BDD with Godog](https://github.com/cucumber/godog)
- [GORM Documentation](https://gorm.io/)
- [Testify Mock](https://github.com/stretchr/testify)
- [Swaggo OpenAPI](https://github.com/swaggo/swag)
- [Chi Router](https://github.com/go-chi/chi)
This workflow ensures consistent, high-quality implementation of user stories while maintaining test coverage and documentation standards throughout the development process.