12 KiB
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
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
## 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
# 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:
# 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
# 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
// 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
// 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
// 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:
# 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
# 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
// 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
# .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:
## 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:
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:
- ✅ Create BDD test (failing)
- ✅ Implement service with mock repository
- ✅ Write unit tests
- ✅ Add GORM repository implementation
- ✅ Update database schema
- ✅ BDD test passes
- ✅ Add OpenAPI documentation
- ✅ CI/CD validation
- ✅ 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
- Focus on behavior, not implementation
- One scenario per test case
- Use clear, descriptive language
- Include both happy and error paths
- Keep scenarios independent
Service Implementation
- Interface-based design for testability
- Context-aware methods
- Proper error handling and logging
- Input validation at service level
- Separation of concerns between layers
Repository Pattern
- Interface first, implementation second
- Database-agnostic design
- Transaction support where needed
- Efficient queries
- Proper error mapping
API Design
- RESTful endpoints
- Consistent response formats
- Proper HTTP status codes
- Comprehensive OpenAPI documentation
- Rate limiting for public endpoints
🔄 Feedback Loop
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
This workflow ensures consistent, high-quality implementation of user stories while maintaining test coverage and documentation standards throughout the development process.