Updated documentaion

master
oabrivard 7 months ago
parent b4f03f9a77
commit f919bfb58f

@ -1,369 +0,0 @@
# Know Foolery - Claude Code Project Guide
## Project Overview
Know Foolery is a cross-platform quiz game with a Go microservices backend and React/React Native frontend using Gluestack UI. This document provides guidance for future Claude Code sessions.
## Project Structure
```
knowfoolery/
├── docs/ # Project documentation
│ ├── architecture.md # System architecture
│ ├── api-specs.md # API specifications
│ └── deployment.md # Deployment guides
├── backend/ # Go microservices
│ ├── services/ # Individual microservices
│ │ ├── game-service/ # Game logic and session management
│ │ ├── question-service/ # Question CRUD operations
│ │ ├── user-service/ # User management
│ │ ├── leaderboard-service/ # Score and ranking logic
│ │ ├── session-service/ # Session and timer management
│ │ ├── admin-service/ # Admin panel backend
│ │ └── gateway-service/ # API gateway
│ ├── shared/ # Shared Go packages
│ │ ├── auth/ # JWT middleware and Zitadel integration
│ │ ├── database/ # Ent database client
│ │ ├── observability/ # Metrics and tracing
│ │ └── security/ # Security utilities
│ └── scripts/ # Build and deployment scripts
├── frontend/ # Cross-platform frontend
│ ├── packages/ # Shared packages
│ │ ├── ui-components/ # Gluestack UI components
│ │ ├── shared-logic/ # Business logic
│ │ └── shared-types/ # TypeScript types
│ ├── web/ # React web application
│ ├── mobile/ # React Native mobile app
│ └── desktop/ # Electron desktop app (future)
├── infrastructure/ # Infrastructure as code
│ ├── docker/ # Docker configurations
│ ├── kubernetes/ # K8s manifests
│ └── monitoring/ # Observability configs
├── tests/ # Testing utilities
│ ├── e2e/ # End-to-end tests
│ ├── load/ # Performance tests
│ └── security/ # Security tests
├── requirements.md # Project requirements
└── README.md # Setup and development guide
```
## Technology Stack
### Backend (Go)
- **Framework**: Fiber for HTTP routing
- **Database ORM**: Ent with PostgreSQL
- **Authentication**: Zitadel OAuth 2.0/OIDC
- **Observability**: Prometheus metrics, OpenTelemetry tracing
- **Communication**: gRPC for inter-service communication
- **Testing**: Go testing + testcontainers
- **Security**: Comprehensive input validation, JWT middleware
### Frontend (TypeScript)
- **Web**: React 18 with TypeScript
- **Mobile**: React Native with TypeScript
- **UI Framework**: Gluestack UI with NativeWind/Tailwind CSS
- **State Management**: React Context + useReducer
- **Testing**: Jest + React Testing Library + Playwright
### Database & Infrastructure
- **Primary Database**: PostgreSQL with Ent ORM
- **Cache**: Redis for sessions and performance
- **Authentication**: Self-hosted Zitadel
- **Deployment**: Docker + Kubernetes
- **Monitoring**: Prometheus + Grafana + Jaeger
## Key Architectural Decisions
### 1. Database Strategy
- **Development**: SQLite for fast local development
- **Testing**: PostgreSQL with testcontainers
- **Production**: PostgreSQL with high availability
- **ORM**: Ent (Facebook) for type-safe database operations
- **No Repository Pattern**: Direct Ent usage except for external APIs
### 2. Authentication Strategy
- **Local Development**: Mock JWT service
- **Production**: Self-hosted Zitadel
- **Repository Pattern**: Only for external integrations (Zitadel)
- **Security**: MFA required for admin accounts
### 3. Cross-Platform UI Strategy
- **Design System**: Gluestack UI for consistent components
- **Styling**: NativeWind/Tailwind CSS for utility-first styling
- **Code Sharing**: Same components work on web and mobile
- **Performance**: Native performance on mobile, optimized for web
## Development Guidelines
### Code Organization
```go
// Backend service structure
services/
├── game-service/
│ ├── cmd/main.go # Service entry point
│ ├── internal/
│ │ ├── handlers/ # HTTP handlers
│ │ ├── services/ # Business logic
│ │ └── models/ # Ent models
│ ├── api/ # API definitions
│ └── tests/ # Service tests
```
```typescript
// Frontend component structure
packages/ui-components/
├── src/
│ ├── GameCard/
│ │ ├── GameCard.tsx # Main component
│ │ ├── GameCard.test.tsx # Tests
│ │ └── index.ts # Exports
│ └── index.ts # Package exports
```
### Naming Conventions
- **Go**: PascalCase for exported, camelCase for unexported
- **TypeScript**: PascalCase for components, camelCase for functions
- **Files**: kebab-case for directories, PascalCase for components
- **Database**: snake_case for tables and columns
### Testing Standards
- **Unit Tests**: Required for all business logic
- **Integration Tests**: Required for database operations
- **E2E Tests**: Required for critical user journeys
- **Security Tests**: Required for all input validation
- **Performance Tests**: Required for high-load scenarios
## Security Requirements
### Critical Security Measures (Implemented Early)
1. **Input Validation**: All user inputs sanitized and validated
2. **SQL Injection Prevention**: Ent parameterized queries only
3. **XSS Protection**: HTML escaping and CSP headers
4. **Authentication**: JWT validation with secure middleware
5. **Rate Limiting**: Per-user and global rate limits
6. **HTTPS**: TLS encryption for all communications
7. **CORS**: Strict cross-origin policies
### Game Integrity
- **Server-Side Validation**: All game logic on backend
- **Score Verification**: Server calculates all scores
- **Session Security**: Tamper-proof session management
- **Anti-Cheating**: Multiple validation layers
## Common Commands
### Backend Development
```bash
# Start all services locally
docker-compose up -d
# Run specific service
cd ~/Projects/go/src/knowfoolery/backend/services/game-service
go run cmd/main.go
# Run tests with coverage
go test -v -cover ./...
# Generate Ent code
cd ~/Projects/go/src/knowfoolery/database/ent
go run -mod=mod entgo.io/ent/cmd/ent describe ./schema
# Update database schema description from Ent code
cd ~/Projects/go/src/knowfoolery/database/ent
go run -mod=mod entgo.io/ent/cmd/ent describe ./schema > ./schema/schema.md
```
### Frontend Development
```bash
# Install dependencies
npm install
# Start web development
cd ~/Projects/go/src/knowfoolery/frontend/web
npm run dev
# Start mobile development
cd ~/Projects/go/src/knowfoolery/frontend/mobile
npm run ios # or npm run android
# Run tests
npm test
# Build for production
npm run build
```
### Database Operations
```bash
# Run migrations
go run ~/Projects/go/src/knowfoolery/backend/scripts/migrate.go
# Reset database (development only)
go run ~/Projects/go/src/knowfoolery/backend/scripts/reset-db.go
# Seed test data
go run ~/Projects/go/src/knowfoolery/backend/scripts/seed.go
```
## Environment Configuration
### Development (.env.dev)
```bash
# Database
DATABASE_URL=sqlite://./dev.db
REDIS_URL=redis://localhost:6379
# Authentication
JWT_SECRET=dev-secret-key
ZITADEL_URL=http://localhost:8080
# Observability
PROMETHEUS_PORT=9090
JAEGER_ENDPOINT=http://localhost:14268
```
### Production (.env.prod)
```bash
# Database
DATABASE_URL=postgres://user:pass@db:5432/knowfoolery
REDIS_URL=redis://redis:6379
# Authentication
JWT_SECRET=${JWT_SECRET}
ZITADEL_URL=${ZITADEL_URL}
# Observability
PROMETHEUS_PORT=9090
JAEGER_ENDPOINT=${JAEGER_ENDPOINT}
```
## Development Workflow
### 1. Feature Development
1. Create feature branch from main
2. Implement domain model changes
3. Add comprehensive tests for domain model
3. Implement database and ORM changes
3. Add comprehensive tests for domain model
2. Implement backend service changes
3. Add comprehensive tests
4. Implement frontend components
5. Test cross-platform compatibility
6. Update documentation
7. Create pull request
### 2. Testing Checklist
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Security tests pass
- [ ] E2E tests pass
- [ ] Cross-platform UI tests pass
- [ ] Performance tests pass
### 3. Deployment Process
1. Merge to main branch
2. Automated CI/CD pipeline
3. Deploy to staging environment
4. Run smoke tests
5. Deploy to production
6. Monitor metrics and alerts
## Troubleshooting
### Common Issues
#### Database Connection Errors
```bash
# Check database status
docker-compose ps
# Reset database connection
docker-compose restart postgres
# Check logs
docker-compose logs postgres
```
#### Authentication Issues
```bash
# Verify JWT token
curl -H "Authorization: Bearer $TOKEN" localhost:8080/api/health
# Check Zitadel status
curl localhost:8080/.well-known/openid_configuration
```
#### Frontend Build Issues
```bash
# Clear node modules
rm -rf node_modules package-lock.json
npm install
# Clear build cache
npm run clean
npm run build
```
## Performance Optimization
### Backend Optimization
- Use Ent query optimization
- Implement Redis caching
- Profile with pprof
- Monitor with Prometheus
### Frontend Optimization
- Bundle size analysis
- React Native performance profiling
- Gluestack UI optimization
- Image and asset optimization
## Security Checklist
### Before Each Release
- [ ] Security dependencies updated
- [ ] Vulnerability scan passed
- [ ] Penetration testing completed
- [ ] Security headers configured
- [ ] Input validation tested
- [ ] Authentication flows verified
- [ ] Rate limiting tested
- [ ] Audit logs reviewed
## Monitoring and Alerts
### Key Metrics to Watch
- **Response Times**: API endpoint performance
- **Error Rates**: Application stability
- **Authentication**: Success/failure rates
- **Game Metrics**: Session duration, completion rates
- **Security Events**: Failed logins, rate limit hits
### Alert Conditions
- API response time > 500ms
- Error rate > 1%
- Authentication failure rate > 5%
- Database connection issues
- Security events detected
## Future Development Notes
### Mobile App Considerations
- Platform-specific optimizations needed
- App store submission requirements
- Push notification integration
- Offline capability planning
### Desktop App Considerations
- Electron performance optimization
- Native OS integration
- Auto-update mechanism
- Platform-specific packaging
### Scalability Planning
- Horizontal scaling strategies
- Database sharding considerations
- CDN integration for global reach
- Microservice boundaries refinement
This guide should be updated as the project evolves and new decisions are made.

@ -1,392 +0,0 @@
# Progressive Phase 1 Implementation Plan: Incremental Infrastructure Setup
## Overview
Instead of setting up all infrastructure at once, we'll progressively build Phase 1 in three distinct sub-phases, allowing for thorough testing and validation at each layer before adding complexity.
## Phase 1A: Backend + Database Foundation (5-7 days)
### Core Infrastructure Setup
**Dependencies: None**
**1A.1 Go Project Structure & Basic Services**
- Create complete Go module structure for all microservices
- Implement basic Fiber apps with health endpoints for each service
- Set up shared packages structure (auth, database, observability, security)
- Create basic service discovery and configuration management
- Add graceful shutdown and signal handling
**1A.2 Database Layer with Ent**
- Define complete Ent schemas (Question, GameSession, QuestionAttempt)
- Set up dual database configuration (SQLite for dev, PostgreSQL for testing)
- Create migration scripts and database initialization
- Implement basic CRUD operations for each entity
- Add database connection pooling and health checks
**1A.3 Mock Authentication System**
- Create simple JWT-based mock authentication (no external calls)
- Implement basic role-based access control (player/admin)
- Add middleware for token validation using local secret
- Create user context propagation through services
- Add basic security headers and CORS
**1A.4 Basic Docker Environment**
- Create `docker-compose.basic.yml` with only PostgreSQL
- Add database initialization and seeding containers
- Create health check scripts for database connectivity
- Set up volume management for persistent data
**1A.5 Integration Testing Framework**
- Set up testcontainers for PostgreSQL integration tests
- Create test utilities for database seeding and cleanup
- Implement service-level integration tests
- Add API endpoint testing with mock authentication
- Create test data factories and fixtures
**Success Criteria for 1A:**
- All services start and respond to health checks
- Database migrations run successfully
- Mock authentication validates tokens correctly
- Integration tests pass with PostgreSQL container
- Services can perform basic CRUD operations
- Docker environment runs consistently
---
## Phase 1B: Add Redis Layer (2-3 days)
### Redis Integration
**Dependencies: Phase 1A complete**
**1B.1 Redis Configuration & Connection**
- Add Redis client to shared package with connection pooling
- Create Redis health checks and monitoring
- Implement connection retry logic and circuit breaker
- Add Redis configuration management (cluster vs single instance)
**1B.2 Session Management with Redis**
- Migrate session storage from in-memory to Redis
- Implement session middleware with Redis backend
- Add session invalidation and cleanup routines
- Create session security (encryption, tampering protection)
**1B.3 Caching Layer Implementation**
- Create cache abstraction layer for future use
- Add caching for frequently accessed data (questions, leaderboards)
- Implement cache invalidation strategies
- Add cache performance metrics
**1B.4 Update Development Environment**
- Extend `docker-compose.basic.yml` to include Redis
- Create `docker-compose.redis.yml` configuration
- Update health check scripts to verify Redis connectivity
- Add Redis monitoring and debugging tools
**1B.5 Redis Integration Testing**
- Extend integration tests to include Redis functionality
- Test session persistence across service restarts
- Validate cache behavior and invalidation
- Test Redis failover scenarios
- Add performance testing for cache operations
**Success Criteria for 1B:**
- Redis connects reliably with proper failover
- Sessions persist correctly in Redis
- Cache operations perform as expected
- Integration tests pass with Redis + PostgreSQL
- Services handle Redis connectivity issues gracefully
---
## Phase 1C: Add Zitadel Authentication (3-4 days)
### External Authentication Integration
**Dependencies: Phase 1B complete**
**1C.1 Zitadel Repository Implementation**
- Implement full ZitadelRepository interface with HTTP client
- Add JWT token validation with Zitadel public keys
- Create token refresh and user management functionality
- Implement circuit breaker for external API calls
- Add proper error handling and retry logic
**1C.2 Replace Mock Authentication**
- Migrate from mock JWT to real Zitadel integration
- Update middleware to validate tokens against Zitadel
- Implement proper role and permission mapping
- Add MFA validation for admin endpoints
- Create user context enrichment from Zitadel claims
**1C.3 Complete Docker Environment**
- Add Zitadel container to Docker Compose setup
- Create `docker-compose.yml` with full infrastructure stack
- Configure Zitadel with proper OAuth applications
- Set up development user accounts and roles
- Add monitoring for all services
**1C.4 Observability Foundation**
- Add Prometheus metrics collection to all services
- Create basic Grafana dashboards
- Implement distributed tracing preparation
- Add structured logging across services
- Create alerting for critical failures
**1C.5 End-to-End Integration Testing**
- Create full authentication flow tests
- Test token validation and refresh cycles
- Validate role-based access control
- Test multi-service communication with real auth
- Add performance testing under load
**Success Criteria for 1C:**
- Zitadel authentication works end-to-end
- All services integrate properly with real JWT validation
- Role-based access control functions correctly
- Integration tests pass with full infrastructure stack
- System handles authentication failures gracefully
- Basic observability provides useful insights
---
## Progressive Testing Strategy
### Phase 1A Testing Focus
- Database operations and data consistency
- Service startup and health check reliability
- Mock authentication token flows
- Basic API functionality
### Phase 1B Testing Focus
- Redis connectivity and session persistence
- Cache performance and invalidation
- Service behavior with Redis failures
- Session security and tampering protection
### Phase 1C Testing Focus
- External authentication integration
- Token validation and refresh flows
- Role-based access across services
- System resilience under auth failures
- End-to-end user workflows
## Benefits of Progressive Approach
1. **Incremental Complexity**: Each phase adds one major component
2. **Isolation of Issues**: Problems can be traced to specific layers
3. **Thorough Testing**: Each layer gets comprehensive validation
4. **Rollback Capability**: Can revert to previous working state
5. **Learning Curve**: Understand each technology deeply before combining
6. **Debugging Ease**: Fewer variables when troubleshooting
7. **Confidence Building**: Success at each phase builds momentum
## Deliverables Timeline
- **Week 1**: Phase 1A - Backend + Database foundation
- **Week 2**: Phase 1B - Redis integration and testing
- **Week 2-3**: Phase 1C - Zitadel integration and full stack testing
This progressive approach ensures solid foundations at each layer before adding the next level of complexity, making the overall implementation more reliable and maintainable.
---
## Detailed Implementation Steps for Phase 1A
### Step 1A.1: Create Go Project Structure
#### Root Go Module Setup
```bash
# Initialize main go.mod
go mod init knowfoolery
go mod tidy
```
#### Directory Structure Creation
```
knowfoolery/
├── backend/
│ ├── services/
│ │ ├── game-service/
│ │ │ ├── cmd/main.go
│ │ │ ├── internal/
│ │ │ │ ├── handlers/
│ │ │ │ ├── services/
│ │ │ │ ├── middleware/
│ │ │ │ └── models/
│ │ │ ├── config/
│ │ │ ├── tests/
│ │ │ └── go.mod
│ │ ├── question-service/
│ │ ├── user-service/
│ │ ├── leaderboard-service/
│ │ ├── session-service/
│ │ ├── admin-service/
│ │ └── gateway-service/
│ ├── shared/
│ │ ├── auth/
│ │ ├── database/
│ │ ├── observability/
│ │ ├── security/
│ │ └── utils/
│ └── scripts/
└── infrastructure/
└── docker/
```
### Step 1A.2: Define Ent Schemas
#### Question Schema
```go
// backend/shared/database/ent/schema/question.go
package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
type Question struct {
ent.Schema
}
func (Question) Fields() []ent.Field {
return []ent.Field{
field.String("id").Unique(),
field.String("theme").NotEmpty(),
field.Text("text").NotEmpty(),
field.String("answer").NotEmpty(),
field.Text("hint").Optional(),
field.Enum("difficulty").Values("easy", "medium", "hard").Default("medium"),
field.Bool("is_active").Default(true),
field.Time("created_at").Default(time.Now),
field.Time("updated_at").Default(time.Now).UpdateDefault(time.Now),
}
}
func (Question) Indexes() []ent.Index {
return []ent.Index{
index.Fields("theme"),
index.Fields("difficulty"),
index.Fields("is_active"),
index.Fields("created_at"),
}
}
```
### Step 1A.3: Basic Service Implementation
#### Game Service Main
```go
// backend/services/game-service/cmd/main.go
package main
import (
"log"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/logger"
)
func main() {
app := fiber.New(fiber.Config{
AppName: "Know Foolery Game Service",
})
// Middleware
app.Use(logger.New())
app.Use(cors.New())
// Health endpoint
app.Get("/health", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"status": "healthy",
"service": "game-service",
})
})
log.Println("Game Service starting on :3001")
log.Fatal(app.Listen(":3001"))
}
```
### Step 1A.4: Docker Compose Basic Setup
#### Basic Docker Compose
```yaml
# infrastructure/docker/docker-compose.basic.yml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: knowfoolery
POSTGRES_USER: knowfoolery
POSTGRES_PASSWORD: dev-password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U knowfoolery"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
```
### Step 1A.5: Integration Test Framework
#### Test Utilities
```go
// backend/shared/database/testutil/testutil.go
package testutil
import (
"context"
"testing"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
)
func SetupTestDB(t *testing.T) (*ent.Client, func()) {
ctx := context.Background()
postgresContainer, err := postgres.RunContainer(ctx,
testcontainers.WithImage("postgres:15-alpine"),
postgres.WithDatabase("testdb"),
postgres.WithUsername("test"),
postgres.WithPassword("test"),
)
if err != nil {
t.Fatal(err)
}
// Get connection string and create Ent client
// ... implementation details
cleanup := func() {
postgresContainer.Terminate(ctx)
}
return client, cleanup
}
```
## Current Phase 1A Implementation Checklist
- [ ] Create complete Go project structure
- [ ] Initialize all service modules with basic Fiber apps
- [ ] Define and generate all Ent schemas
- [ ] Set up database connection and migration utilities
- [ ] Implement mock JWT authentication
- [ ] Create Docker Compose basic environment
- [ ] Set up integration testing framework
- [ ] Add health checks and basic monitoring
- [ ] Create database seeding scripts
- [ ] Validate all services start and communicate properly
This detailed plan provides clear, actionable steps for implementing Phase 1A while maintaining the progressive approach that allows for thorough testing at each layer.

@ -1,157 +0,0 @@
# Know Foolery - Claude Implementation Plan
## Project Overview
**Know Foolery** is a comprehensive quiz game application based on the French game "Déconnaissance". The project implements a cross-platform solution with web, mobile (iOS/Android), and desktop applications, featuring secure authentication, microservices architecture, and comprehensive observability.
## Technology Stack
- **Backend**: Go with Fiber framework, microservices architecture
- **Database**: PostgreSQL (production), SQLite (development)
- **ORM**: Ent for type-safe database operations
- **Cache**: Redis for session management and caching
- **Authentication**: Self-hosted Zitadel (OAuth 2.0/OIDC)
- **Frontend**: React (web), React Native (mobile), Wails (desktop)
- **UI Framework**: Gluestack UI for cross-platform consistency
- **Styling**: NativeWind/Tailwind CSS
- **Monitoring**: Prometheus, Grafana, Jaeger
- **Containerization**: Docker with Docker Compose
## Implementation Phases
### Phase 0: Documentation & Planning ✅ COMPLETED
- [x] Create requirements.md with complete application requirements
- [x] Create CLAUDE.md project guidance file
- [x] Document game mechanics and scoring system
- [x] Document technical requirements and architecture decisions
- [x] Create architecture documentation with Zitadel integration
- [x] Document development guidelines and coding standards
- [x] Document observability strategy
- [x] Document security requirements
- [x] Document cross-platform UI strategy with Gluestack UI
**Completion Date**: Phase 0 completed successfully with comprehensive documentation covering all aspects of the project.
### Phase 1: Project Setup & Core Security Infrastructure
- [ ] Initialize Go project structure with microservices architecture
- [ ] Set up Ent schema definitions for core entities (User, Quiz, Question, etc.)
- [ ] Create ZitadelRepository interface for external auth integration
- [ ] Set up development environment with Docker Compose
- [ ] Initialize Gluestack UI setup with theme configuration
- [ ] Implement core security middleware and input validation
- [ ] Set up Prometheus metrics collection foundation
- [ ] Create basic CI/CD pipeline structure
### Phase 2: Authentication & User Management
- [ ] Implement Zitadel integration with repository pattern
- [ ] Create JWT validation middleware with circuit breaker
- [ ] Build user registration and profile management
- [ ] Implement role-based access control (player/admin)
- [ ] Add MFA requirements for admin access
- [ ] Create secure token storage for each platform
- [ ] Implement comprehensive authentication testing
### Phase 3: Core Game Engine
- [ ] Implement quiz engine with theme and difficulty support
- [ ] Create question management system with validation
- [ ] Build scoring system with anti-cheating measures
- [ ] Implement session management (30-minute time limits)
- [ ] Add hint system with progressive revelation
- [ ] Create leaderboard functionality
- [ ] Implement comprehensive game testing
### Phase 4: Cross-Platform Frontend
- [ ] Build React web application with Gluestack UI
- [ ] Create React Native mobile applications
- [ ] Develop Wails desktop application
- [ ] Implement shared authentication flows
- [ ] Create responsive game interface components
- [ ] Add platform-specific optimizations
- [ ] Implement comprehensive frontend testing
### Phase 5: Admin Panel & Content Management
- [ ] Build secure admin dashboard
- [ ] Create question management interface
- [ ] Implement user administration tools
- [ ] Add analytics and reporting features
- [ ] Create content import/export functionality
- [ ] Implement admin-specific security measures
- [ ] Add comprehensive admin testing
### Phase 6: Performance & Optimization
- [ ] Implement Redis caching strategy
- [ ] Add database query optimization
- [ ] Create CDN integration for assets
- [ ] Implement API rate limiting
- [ ] Add frontend performance optimization
- [ ] Create load testing and benchmarks
### Phase 7: Monitoring & Observability
- [ ] Complete Prometheus metrics implementation
- [ ] Set up Grafana dashboards
- [ ] Implement distributed tracing with Jaeger
- [ ] Add comprehensive logging strategy
- [ ] Create alerting and notification system
- [ ] Implement health checks and monitoring
### Phase 8: Security Hardening
- [ ] Conduct comprehensive security audit
- [ ] Implement advanced anti-cheating measures
- [ ] Add security monitoring and incident response
- [ ] Create backup and disaster recovery procedures
- [ ] Implement data encryption at rest
- [ ] Add comprehensive security testing
### Phase 9: Production Deployment
- [ ] Set up production infrastructure
- [ ] Configure CI/CD for production deployment
- [ ] Implement monitoring and alerting in production
- [ ] Create deployment documentation
- [ ] Conduct production readiness review
- [ ] Implement production security measures
### Phase 10: Launch & Post-Launch
- [ ] Conduct final testing and quality assurance
- [ ] Deploy to production environment
- [ ] Monitor launch metrics and performance
- [ ] Address any post-launch issues
- [ ] Gather user feedback and analytics
- [ ] Plan future feature development
## Key Architectural Decisions
1. **Repository Pattern**: Used only for external API integrations (Zitadel), direct Ent client usage for database operations
2. **Security First**: Critical vulnerabilities addressed in early phases (1-3), enhancements in Phase 8
3. **Cross-Platform UI**: Gluestack UI for consistent design across web, mobile, and desktop
4. **Microservices**: Go with Fiber framework for high-performance, maintainable services
5. **Self-Hosted Auth**: Zitadel for complete control over authentication and user data
6. **Comprehensive Testing**: Unit and integration testing after each implementation phase
## Current Status
**Phase 0 Complete**: All documentation has been created and is ready for implementation. The project has comprehensive documentation covering:
- Complete requirements and specifications
- Technical architecture with microservices design
- Security requirements and implementation strategy
- Cross-platform UI strategy with Gluestack UI
- Development guidelines and coding standards
- Observability and monitoring strategy
- Game mechanics and anti-cheating measures
- Zitadel authentication integration
**Next Steps**: Ready to begin Phase 1 (Project Setup & Core Security Infrastructure) upon approval to proceed with implementation.
## Files Created
1. `/requirements.md` - Complete project requirements and specifications
2. `/CLAUDE.md` - Project guidance for future Claude Code sessions
3. `/docs/game-mechanics.md` - Game flow, scoring, and anti-cheating measures
4. `/docs/technical-architecture.md` - System architecture and service design
5. `/docs/zitadel-integration.md` - Authentication architecture and implementation
6. `/docs/development-guidelines.md` - Coding standards and patterns
7. `/docs/observability-strategy.md` - Monitoring and metrics strategy
8. `/docs/security-requirements.md` - Security strategy and requirements
9. `/docs/gluestack-ui-strategy.md` - Cross-platform UI implementation strategy
All documentation includes comprehensive code examples, implementation details, and best practices for building a secure, scalable quiz game application.

@ -110,3 +110,21 @@ Zitadel serves as the self-hosted OAuth 2.0/OpenID Connect authentication provid
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
```
### Authentication Flow
```mermaid
sequenceDiagram
participant C as Client
participant G as API Gateway
participant Z as Zitadel
participant S as Service
C->>G: Request with credentials
G->>Z: Validate credentials
Z->>G: Return JWT token
G->>C: Return token + user info
C->>G: API request with JWT
G->>G: Validate JWT signature
G->>S: Forward request with user context
S->>G: Return response
G->>C: Return response
```

@ -8,19 +8,24 @@ Know Foolery follows a microservices architecture with clear separation between
## Technical Architecture
### Frontend Architecture
- **Web Application**: React with TypeScript
- **Mobile Applications**: React Native for iOS and Android
- **Desktop Applications**: Wails for macOS, Windows, and Linux
- **Web Application**: React with TypeScript, vite and React Native Web
- **Mobile Applications**: React Native with Expo for iOS and Android
- **Desktop Applications**: Wails for macOS, Windows, and Linux, with the web application packaged for the deployement in the Wails app
- **UI Framework**: Gluestack UI for consistent cross-platform design
- **Styling**: NativeWind/Tailwind CSS for utility-first styling
### Backend Architecture
- **Business Logic**: Domain Driven Design approach
- **Microservices**: Go-based services with clear domain boundaries
- **API Gateway**: Centralized routing, authentication, and rate limiting
- **Database ORM**: Ent for type-safe database operations
- **Communication**: gRPC for inter-service communication
- **External APIs**: Repository pattern for external integrations
### Domain Design
- **Aggregates**: User, Theme, Question, GameSession
- **Value Objects**: Hint, Attempt, Answer, Score
- **Domain Services**: Scoring
### Microservices Design
#### Core Services
@ -29,31 +34,33 @@ Know Foolery follows a microservices architecture with clear separation between
3. **User Service**: Player registration and profile management
4. **Leaderboard Service**: Score calculations, rankings, statistics
5. **Session Service**: Timer management, session state persistence
6. **Admin Service**: Question management with OAuth protection
6. **Admin Service**: Question and user management with OAuth protection
7. **Gateway Service**: API routing, authentication, rate limiting
#### External Services
1. **Zitadel**: Self-hosted OAuth 2.0/OIDC authentication
2. **PostgreSQL**: Primary database for application data
3. **Redis**: Session state and caching layer
2. **PostgreSQL**: Primary database for production application data
3. **sqlite**: Database for test application data
4. **Redis**: Session state and caching layer
### Database Design
#### Core Entities
- **Questions**: ID, theme, text, answer, hint, metadata
- **GameSessions**: ID, player_name, score, start_time, end_time, is_active
- **Users**: ID, name, created_at (minimal player data)
- **Themes**: ID, theme, metadata
- **Questions**: ID, ID of theme, text, answer, hint, metadata
- **GameSessions**: ID, ID of user, score, start_time, end_time, is_active
- **Attempts**: ID, ID of GameSession, answer
- **Leaderboard**: Aggregated scores and rankings
- **AuditLogs**: Admin actions and security events
#### Data Relationships
- Questions belong to themes
- GameSessions track multiple question attempts
- GameSessions track multiple question attempts for a user
- Leaderboard aggregates from GameSessions
- AuditLogs reference users and actions
## Deployment & Infrastructure
### Development Environment
@ -70,8 +77,7 @@ Know Foolery follows a microservices architecture with clear separation between
### Cross-Platform Deployment
- **Web**: Standard web application deployment
- **Mobile**: iOS App Store and Google Play Store distribution
- **Desktop**: Electron applications for major operating systems
- **Desktop**: Wails applications for major operating systems
## System Architecture Diagram
@ -79,10 +85,10 @@ Know Foolery follows a microservices architecture with clear separation between
```
┌────────────────────────────────────────────────────────────────────────────┐
│ Client Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ Web App │ │ Mobile iOS │ │ Mobile Androi│ │ Desktop ctr│ │
│ │ (React) │ │(React Native)│ │(React Native)│ │ (Wails) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └─────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ Web App │ │ Mobile iOS │ │ Mobile Android│ │ Desktop │ │
│ │ (React) │ │(React Native)│ │(React Native) │ │ (Wails) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └─────────────┘ │
└────────────────────────────────────────────────────────────────────────────┘
HTTPS/WSS
@ -125,6 +131,10 @@ Know Foolery follows a microservices architecture with clear separation between
```
## Technology Stack
- **Web Application**: React with TypeScript, vite and React Native Web
- **Mobile Applications**: React Native with Expo for iOS and Android
- **Desktop Applications**: Wails for macOS, Windows, and Linux, with the web application packaged for the deployement in the Wails app
- **UI Framework**: Gluestack UI for consistent cross-platform design
### Frontend Technologies
```yaml
@ -132,7 +142,7 @@ Web Application:
Framework: React 18.2+
Language: TypeScript 5.0+
Build Tool: Vite 4.0+
UI Library: Gluestack UI
UI Library: Gluestack UI (React Native Web)
Styling: NativeWind/Tailwind CSS 3.0+
State Management: React Context + useReducer
Testing: Jest + React Testing Library + Playwright
@ -141,7 +151,7 @@ Mobile Applications:
Framework: React Native 0.81+
Language: TypeScript 5.9+
UI Library: Gluestack UI (Native)
Navigation: React Navigation 6+
Navigation: Expo 54+
State Management: React Context + useReducer
Testing: Jest + React Native Testing Library
@ -214,15 +224,6 @@ CI/CD:
#### 1. Game Service
```go
// Responsibilities
type GameService struct {
// Core game logic and session management
SessionManager *SessionManager
ScoreCalculator *ScoreCalculator
AttemptTracker *AttemptTracker
TimerManager *TimerManager
}
// API Endpoints
POST /api/v1/game/start // Start new game session
GET /api/v1/game/session/{id} // Get session details
@ -234,49 +235,32 @@ GET /api/v1/game/status/{id} // Get session status
#### 2. Question Service
```go
// Responsibilities
type QuestionService struct {
QuestionRepo *QuestionRepository
ThemeManager *ThemeManager
Randomizer *QuestionRandomizer
Validator *AnswerValidator
}
// API Endpoints
GET /api/v1/questions/random // Get random question
GET /api/v1/questions/{id} // Get specific question
GET /api/v1/questions/themes // List available themes
POST /api/v1/questions // Create question (admin)
PUT /api/v1/questions/{id} // Update question (admin)
DELETE /api/v1/questions/{id} // Delete question (admin)
GET /api/v1/questions/themes/random/{id} // Get random question in a theme
GET /api/v1/questions/random // Get random question in a theme
GET /api/v1/questions/{id} // Get specific question
GET /api/v1/questions/themes // List available themes
POST /api/v1/questions // Create question (admin)
PUT /api/v1/questions/{id} // Update question (admin)
DELETE /api/v1/questions/{id} // Delete question (admin)
GET /api/v1/questions // List all questions (admin)
POST /api/v1/questions/bulk // Bulk question import (admin)
```
#### 3. User Service
```go
// Responsibilities
type UserService struct {
UserRepo *UserRepository
ProfileManager *ProfileManager
SessionTracker *SessionTracker
}
// API Endpoints
POST /api/v1/users/register // Register new player
GET /api/v1/users/profile // Get user profile
PUT /api/v1/users/profile // Update profile
GET /api/v1/users/sessions // Get session history
DELETE /api/v1/users/profile // Delete account (GDPR)
GET /api/v1/users // List all users (admin)
DELETE /api/v1/users // Delete user (admin)
```
#### 4. Leaderboard Service
```go
// Responsibilities
type LeaderboardService struct {
ScoreAggregator *ScoreAggregator
RankingEngine *RankingEngine
StatsCalculator *StatsCalculator
}
// API Endpoints
GET /api/v1/leaderboard/top10 // Get top 10 scores
GET /api/v1/leaderboard/stats // Get game statistics
@ -286,13 +270,6 @@ POST /api/v1/leaderboard/update // Update scores (internal)
#### 5. Session Service
```go
// Responsibilities
type SessionService struct {
SessionStore *SessionStore
TimerManager *TimerManager
StateManager *StateManager
}
// API Endpoints
POST /api/v1/sessions // Create session
GET /api/v1/sessions/{id} // Get session
@ -303,20 +280,9 @@ GET /api/v1/sessions/{id}/timer // Get timer status
#### 6. Admin Service
```go
// Responsibilities
type AdminService struct {
AuthManager *AuthManager
QuestionMgmt *QuestionManagement
UserMgmt *UserManagement
AuditLogger *AuditLogger
}
// API Endpoints
POST /api/v1/admin/auth // Admin authentication
GET /api/v1/admin/dashboard // Dashboard data
GET /api/v1/admin/questions // List all questions
POST /api/v1/admin/questions/bulk // Bulk question import
GET /api/v1/admin/users // User management
GET /api/v1/admin/audit // Audit logs
```
@ -364,544 +330,4 @@ service LeaderboardService {
}
```
## Database Architecture
### Data Model Design
#### Core Entities (Ent Schemas)
```go
// Question Entity
type Question struct {
ent.Schema
}
func (Question) Fields() []ent.Field {
return []ent.Field{
field.String("theme").NotEmpty(),
field.Text("text").NotEmpty(),
field.String("answer").NotEmpty(),
field.Text("hint").Optional(),
field.Enum("difficulty").Values("easy", "medium", "hard").Default("medium"),
field.Bool("is_active").Default(true),
field.Time("created_at").Default(time.Now),
field.Time("updated_at").Default(time.Now).UpdateDefault(time.Now),
}
}
func (Question) Indexes() []ent.Index {
return []ent.Index{
index.Fields("theme"),
index.Fields("difficulty"),
index.Fields("is_active"),
index.Fields("created_at"),
}
}
// GameSession Entity
type GameSession struct {
ent.Schema
}
func (GameSession) Fields() []ent.Field {
return []ent.Field{
field.String("player_name").NotEmpty(),
field.Int("total_score").Default(0),
field.Int("questions_asked").Default(0),
field.Int("questions_correct").Default(0),
field.Int("hints_used").Default(0),
field.Time("start_time").Default(time.Now),
field.Time("end_time").Optional().Nillable(),
field.Enum("status").Values("active", "completed", "timeout", "abandoned").Default("active"),
field.String("current_question_id").Optional(),
field.Int("current_attempts").Default(0),
}
}
func (GameSession) Edges() []ent.Edge {
return []ent.Edge{
edge.To("attempts", QuestionAttempt.Type),
edge.To("current_question", Question.Type).Unique().Field("current_question_id"),
}
}
// QuestionAttempt Entity
type QuestionAttempt struct {
ent.Schema
}
func (QuestionAttempt) Fields() []ent.Field {
return []ent.Field{
field.String("session_id"),
field.String("question_id"),
field.Int("attempt_number"),
field.String("submitted_answer"),
field.Bool("is_correct"),
field.Bool("used_hint"),
field.Int("points_awarded"),
field.Time("submitted_at").Default(time.Now),
field.Duration("time_taken"),
}
}
func (QuestionAttempt) Edges() []ent.Edge {
return []ent.Edge{
edge.From("session", GameSession.Type).Ref("attempts").Unique().Field("session_id"),
edge.To("question", Question.Type).Unique().Field("question_id"),
}
}
```
#### Database Performance Optimization
```sql
-- Indexes for optimal query performance
CREATE INDEX idx_questions_theme_active ON questions(theme, is_active);
CREATE INDEX idx_sessions_status_start_time ON game_sessions(status, start_time);
CREATE INDEX idx_attempts_session_question ON question_attempts(session_id, question_id);
CREATE INDEX idx_leaderboard_score_time ON game_sessions(total_score DESC, end_time ASC) WHERE status = 'completed';
-- Partitioning for large datasets (future scaling)
CREATE TABLE game_sessions_y2024m01 PARTITION OF game_sessions
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
```
### Database Connection Management
```go
// Database configuration
type DatabaseConfig struct {
Primary DatabaseInstance
Replicas []DatabaseInstance
Pool PoolConfig
}
type DatabaseInstance struct {
Host string
Port int
Database string
Username string
Password string
SSLMode string
}
type PoolConfig struct {
MaxOpenConns int // 25
MaxIdleConns int // 5
ConnMaxLifetime time.Duration // 30 minutes
ConnMaxIdleTime time.Duration // 15 minutes
}
// Connection pooling with read/write splitting
func NewDatabaseClient(config DatabaseConfig) (*ent.Client, error) {
primaryDSN := formatDSN(config.Primary)
// Primary database for writes
primaryDB, err := sql.Open("postgres", primaryDSN)
if err != nil {
return nil, err
}
configurePools(primaryDB, config.Pool)
// Create Ent client with instrumented driver
drv := entsql.OpenDB("postgres", primaryDB)
return ent.NewClient(ent.Driver(drv)), nil
}
```
## Security Architecture
### Authentication Flow
```mermaid
sequenceDiagram
participant C as Client
participant G as API Gateway
participant Z as Zitadel
participant S as Service
C->>G: Request with credentials
G->>Z: Validate credentials
Z->>G: Return JWT token
G->>C: Return token + user info
C->>G: API request with JWT
G->>G: Validate JWT signature
G->>S: Forward request with user context
S->>G: Return response
G->>C: Return response
```
### Authorization Strategy
```go
// Role-based access control
type Role string
const (
RolePlayer Role = "player"
RoleAdmin Role = "admin"
)
type Permissions struct {
CanPlayGame bool
CanViewScores bool
CanManageQuestions bool
CanViewAuditLogs bool
CanManageUsers bool
}
var RolePermissions = map[Role]Permissions{
RolePlayer: {
CanPlayGame: true,
CanViewScores: true,
},
RoleAdmin: {
CanPlayGame: true,
CanViewScores: true,
CanManageQuestions: true,
CanViewAuditLogs: true,
CanManageUsers: true,
},
}
// JWT middleware with role checking
func AuthMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
token := extractToken(c.Get("Authorization"))
claims, err := validateJWT(token)
if err != nil {
return c.Status(401).JSON(fiber.Map{"error": "Invalid token"})
}
c.Locals("user_id", claims.Subject)
c.Locals("user_role", claims.Role)
c.Locals("permissions", RolePermissions[Role(claims.Role)])
return c.Next()
}
}
func RequirePermission(permission func(Permissions) bool) fiber.Handler {
return func(c *fiber.Ctx) error {
perms := c.Locals("permissions").(Permissions)
if !permission(perms) {
return c.Status(403).JSON(fiber.Map{"error": "Insufficient permissions"})
}
return c.Next()
}
}
```
### Input Validation & Security
```go
// Comprehensive input validation
type InputValidator struct {
maxAnswerLength int
maxNameLength int
allowedChars *regexp.Regexp
}
func NewInputValidator() *InputValidator {
return &InputValidator{
maxAnswerLength: 500,
maxNameLength: 50,
allowedChars: regexp.MustCompile(`^[a-zA-Z0-9\s\-_.]+$`),
}
}
func (v *InputValidator) ValidateAnswer(answer string) error {
if len(answer) == 0 {
return errors.New("answer cannot be empty")
}
if len(answer) > v.maxAnswerLength {
return errors.New("answer too long")
}
// Sanitize HTML and potential XSS
clean := html.EscapeString(strings.TrimSpace(answer))
if clean != answer {
return errors.New("invalid characters in answer")
}
return nil
}
func (v *InputValidator) ValidatePlayerName(name string) error {
if len(name) < 2 || len(name) > v.maxNameLength {
return errors.New("name must be 2-50 characters")
}
if !v.allowedChars.MatchString(name) {
return errors.New("name contains invalid characters")
}
return nil
}
// Rate limiting implementation
type RateLimiter struct {
redis *redis.Client
limits map[string]RateLimit
}
type RateLimit struct {
Requests int // Number of requests
Window time.Duration // Time window
}
func (rl *RateLimiter) Allow(key string, limit RateLimit) bool {
current, err := rl.redis.Incr(key).Result()
if err != nil {
return false // Fail closed
}
if current == 1 {
rl.redis.Expire(key, limit.Window)
}
return current <= int64(limit.Requests)
}
// Usage in middleware
func RateLimitMiddleware() fiber.Handler {
limiter := NewRateLimiter()
return func(c *fiber.Ctx) error {
userID := c.Locals("user_id").(string)
clientIP := c.IP()
// Per-user rate limiting
userKey := fmt.Sprintf("rate_limit:user:%s", userID)
if !limiter.Allow(userKey, RateLimit{Requests: 60, Window: time.Minute}) {
return c.Status(429).JSON(fiber.Map{"error": "Rate limit exceeded"})
}
// Per-IP rate limiting
ipKey := fmt.Sprintf("rate_limit:ip:%s", clientIP)
if !limiter.Allow(ipKey, RateLimit{Requests: 100, Window: time.Minute}) {
return c.Status(429).JSON(fiber.Map{"error": "Rate limit exceeded"})
}
return c.Next()
}
}
```
## Cross-Platform Frontend Architecture
### Gluestack UI Integration
```typescript
// Shared component library structure
// packages/ui-components/src/index.ts
export { GameCard } from './GameCard'
export { Leaderboard } from './Leaderboard'
export { Timer } from './Timer'
export { ScoreDisplay } from './ScoreDisplay'
export { AdminPanel } from './AdminPanel'
// Component example with Gluestack UI
// packages/ui-components/src/GameCard/GameCard.tsx
import {
Card,
VStack,
HStack,
Text,
Input,
Button,
Badge,
Progress,
Box
} from '@gluestack-ui/themed'
export interface GameCardProps {
question: string
theme: string
timeRemaining: number
attemptsLeft: number
currentScore: number
onSubmitAnswer: (answer: string) => void
onRequestHint: () => void
isLoading?: boolean
}
export const GameCard: React.FC<GameCardProps> = ({
question,
theme,
timeRemaining,
attemptsLeft,
currentScore,
onSubmitAnswer,
onRequestHint,
isLoading = false
}) => {
const [answer, setAnswer] = useState('')
const handleSubmit = () => {
if (answer.trim()) {
onSubmitAnswer(answer.trim())
setAnswer('')
}
}
return (
<Card size="lg" variant="elevated" m="$4">
<VStack space="md" p="$4">
{/* Header with theme and timer */}
<HStack justifyContent="space-between" alignItems="center">
<Badge size="sm" variant="solid" action="info">
<Text color="$white" fontSize="$sm" fontWeight="$semibold">
{theme}
</Text>
</Badge>
<HStack space="sm" alignItems="center">
<Text fontSize="$sm" color="$textLight600">
⏱️ {Math.floor(timeRemaining / 60)}:{(timeRemaining % 60).toString().padStart(2, '0')}
</Text>
</HStack>
</HStack>
{/* Progress indicator */}
<Progress value={((30 * 60 - timeRemaining) / (30 * 60)) * 100} size="sm">
<ProgressFilledTrack />
</Progress>
{/* Question */}
<Box>
<Text fontSize="$lg" fontWeight="$semibold" lineHeight="$xl">
{question}
</Text>
</Box>
{/* Answer input */}
<Input size="lg" isDisabled={isLoading}>
<InputField
placeholder="Enter your answer..."
value={answer}
onChangeText={setAnswer}
autoCapitalize="none"
autoCorrect={false}
/>
</Input>
{/* Game stats */}
<HStack justifyContent="space-between" alignItems="center">
<Text fontSize="$sm" color="$textLight600">
Attempts left: {attemptsLeft}/3
</Text>
<Text fontSize="$sm" color="$textLight600">
Score: {currentScore} points
</Text>
</HStack>
{/* Action buttons */}
<HStack space="sm">
<Button
size="lg"
variant="solid"
action="primary"
flex={1}
onPress={handleSubmit}
isDisabled={!answer.trim() || isLoading}
>
<ButtonText>Submit Answer</ButtonText>
</Button>
<Button
size="lg"
variant="outline"
action="secondary"
onPress={onRequestHint}
isDisabled={isLoading}
>
<ButtonText>💡 Hint</ButtonText>
</Button>
</HStack>
</VStack>
</Card>
)
}
```
### Platform-Specific Adaptations
```typescript
// Platform detection and adaptation
// packages/shared-logic/src/platform.ts
export interface PlatformCapabilities {
hasTouch: boolean
hasKeyboard: boolean
hasCamera: boolean
canVibrate: boolean
supportsNotifications: boolean
isOfflineCapable: boolean
}
export const getPlatformCapabilities = (): PlatformCapabilities => {
// Web platform
if (typeof window !== 'undefined') {
return {
hasTouch: 'ontouchstart' in window,
hasKeyboard: true,
hasCamera: !!navigator.mediaDevices?.getUserMedia,
canVibrate: !!navigator.vibrate,
supportsNotifications: 'Notification' in window,
isOfflineCapable: 'serviceWorker' in navigator
}
}
// React Native platform
if (typeof require !== 'undefined') {
try {
const { Platform } = require('react-native')
return {
hasTouch: true,
hasKeyboard: Platform.OS === 'ios' || Platform.OS === 'android',
hasCamera: true,
canVibrate: true,
supportsNotifications: true,
isOfflineCapable: true
}
} catch {
// Fallback for other environments
}
}
// Default capabilities
return {
hasTouch: false,
hasKeyboard: true,
hasCamera: false,
canVibrate: false,
supportsNotifications: false,
isOfflineCapable: false
}
}
// Responsive design utilities
export const useResponsiveValue = <T>(values: {
mobile: T
tablet: T
desktop: T
}) => {
const [screenSize, setScreenSize] = useState<'mobile' | 'tablet' | 'desktop'>('desktop')
useEffect(() => {
const updateScreenSize = () => {
const width = window.innerWidth
if (width < 768) {
setScreenSize('mobile')
} else if (width < 1024) {
setScreenSize('tablet')
} else {
setScreenSize('desktop')
}
}
updateScreenSize()
window.addEventListener('resize', updateScreenSize)
return () => window.removeEventListener('resize', updateScreenSize)
}, [])
return values[screenSize]
}
```
This technical architecture provides a solid foundation for building a scalable, secure, and maintainable quiz game platform with cross-platform capabilities.

@ -28,13 +28,14 @@ This document establishes coding standards, development practices, and guideline
```
knowfoolery/
├── backend/
│ ├── services/ # Microservices
│ ├── Domain/ # Domain logic (aggregates, value objects, repositories, services from Domain Driven Design)
│ ├── services/ # Microservices
│ │ ├── {service-name}/
│ │ │ ├── cmd/
│ │ │ │ └── main.go # Service entry point
│ │ │ ├── internal/
│ │ │ │ ├── handlers/ # Fiber HTTP handlers
│ │ │ │ ├── services/ # Business logic
│ │ │ │ ├── app/ # Business logic (commands, queries)
│ │ │ │ ├── middleware/ # Service-specific middleware
│ │ │ │ └── models/ # Ent models and schemas
│ │ │ ├── api/ # API definitions (OpenAPI/gRPC)
@ -45,6 +46,7 @@ knowfoolery/
│ │ └── shared/ # Shared packages
│ │ ├── auth/ # JWT middleware & Zitadel integration
│ │ ├── database/ # Ent database client
│ │ │ │ └── schema/ # Ent models and schemas
│ │ ├── observability/ # Metrics and tracing
│ │ ├── security/ # Security utilities
│ │ └── utils/ # Common utilities
@ -54,11 +56,15 @@ knowfoolery/
│ │ ├── shared-logic/ # Business logic
│ │ ├── shared-types/ # TypeScript types
│ │ └── shared-utils/ # Utility functions
── apps/
├── web/ # React web app
├── mobile/ # React Native app
└── desktop/ # Wails desktop app
── apps/
├── web/ # React web app
├── mobile/ # React Native app
└── desktop/ # Wails desktop app
└── infrastructure/ # DevOps and deployment
├── dev/ # Development setup
│ ├── docker-compose.yml # dev stack (hot reload, mounts)
│ └── api.env # dev env vars
└── prod/ # Production setup
```
### Naming Conventions

@ -3,178 +3,7 @@
## Authentication & Authorization
### OAuth 2.0/OIDC Implementation
#### Zitadel Authentication Flow
```go
// Secure authentication implementation
package auth
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/argon2"
)
type SecureAuthService struct {
zitadelRepo ZitadelRepository
keyStore *KeyStore
sessionManager *SessionManager
auditLogger *AuditLogger
rateLimiter *RateLimiter
}
type AuthClaims struct {
jwt.RegisteredClaims
Email string `json:"email"`
Name string `json:"name"`
Roles []string `json:"urn:zitadel:iam:org:project:roles"`
MFAVerified bool `json:"amr"`
SessionID string `json:"sid"`
DeviceID string `json:"device_id,omitempty"`
IPAddress string `json:"ip_address,omitempty"`
}
// Token validation with comprehensive security checks
func (s *SecureAuthService) ValidateToken(ctx context.Context, tokenString string, clientIP string) (*AuthClaims, error) {
// Rate limiting check
if !s.rateLimiter.Allow(fmt.Sprintf("token_validation:%s", clientIP)) {
s.auditLogger.LogSecurityEvent("rate_limit_exceeded", "", clientIP, "warning", map[string]interface{}{
"operation": "token_validation",
})
return nil, fmt.Errorf("rate limit exceeded")
}
// Parse and validate JWT structure
token, err := jwt.ParseWithClaims(tokenString, &AuthClaims{}, func(token *jwt.Token) (interface{}, error) {
// Verify signing algorithm
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
// Get key ID from header
keyID, ok := token.Header["kid"].(string)
if !ok {
return nil, fmt.Errorf("missing key ID in token header")
}
// Retrieve public key
return s.keyStore.GetPublicKey(keyID)
})
if err != nil {
s.auditLogger.LogSecurityEvent("invalid_token", "", clientIP, "warning", map[string]interface{}{
"error": err.Error(),
})
return nil, fmt.Errorf("token validation failed: %w", err)
}
if !token.Valid {
return nil, fmt.Errorf("invalid token")
}
claims, ok := token.Claims.(*AuthClaims)
if !ok {
return nil, fmt.Errorf("invalid token claims")
}
// Additional security validations
if err := s.validateTokenClaims(claims, clientIP); err != nil {
s.auditLogger.LogSecurityEvent("token_validation_failed", claims.Subject, clientIP, "warning", map[string]interface{}{
"error": err.Error(),
})
return nil, err
}
// Check if session is still valid
if !s.sessionManager.IsValidSession(claims.SessionID, claims.Subject) {
s.auditLogger.LogSecurityEvent("invalid_session", claims.Subject, clientIP, "warning", map[string]interface{}{
"session_id": claims.SessionID,
})
return nil, fmt.Errorf("session no longer valid")
}
// Log successful validation
s.auditLogger.LogSecurityEvent("token_validated", claims.Subject, clientIP, "info", map[string]interface{}{
"session_id": claims.SessionID,
"roles": claims.Roles,
})
return claims, nil
}
func (s *SecureAuthService) validateTokenClaims(claims *AuthClaims, clientIP string) error {
now := time.Now()
// Check expiration
if claims.ExpiresAt != nil && claims.ExpiresAt.Time.Before(now) {
return fmt.Errorf("token expired")
}
// Check not before
if claims.NotBefore != nil && claims.NotBefore.Time.After(now) {
return fmt.Errorf("token not yet valid")
}
// Check issued at (prevent future tokens)
if claims.IssuedAt != nil && claims.IssuedAt.Time.After(now.Add(5*time.Minute)) {
return fmt.Errorf("token issued in the future")
}
// Validate audience
expectedAudience := "knowfoolery-quiz-game"
if !contains(claims.Audience, expectedAudience) {
return fmt.Errorf("invalid audience")
}
// Validate issuer
expectedIssuer := "https://auth.knowfoolery.com"
if claims.Issuer != expectedIssuer {
return fmt.Errorf("invalid issuer")
}
// IP address validation (if configured)
if claims.IPAddress != "" && claims.IPAddress != clientIP {
return fmt.Errorf("IP address mismatch")
}
return nil
}
// Multi-Factor Authentication enforcement
func (s *SecureAuthService) RequireMFA(userID string, roles []string) bool {
// Admin users always require MFA
for _, role := range roles {
if role == "admin" {
return true
}
}
// Check if user has high-value permissions
return s.hasHighValuePermissions(roles)
}
func (s *SecureAuthService) hasHighValuePermissions(roles []string) bool {
highValueRoles := []string{"moderator", "question_manager", "user_manager"}
for _, userRole := range roles {
for _, hvRole := range highValueRoles {
if userRole == hvRole {
return true
}
}
}
return false
}
```
- See [Zitadel Integration Guidelines](zitadel-guidelines.md)
### Session Management
```go

@ -381,6 +381,179 @@ func (cb *CircuitBreaker) setState(state CircuitState) {
## Authentication Flows
### Zitadel Authentication Flow
```go
// Secure authentication implementation
package auth
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/argon2"
)
type SecureAuthService struct {
zitadelRepo ZitadelRepository
keyStore *KeyStore
sessionManager *SessionManager
auditLogger *AuditLogger
rateLimiter *RateLimiter
}
type AuthClaims struct {
jwt.RegisteredClaims
Email string `json:"email"`
Name string `json:"name"`
Roles []string `json:"urn:zitadel:iam:org:project:roles"`
MFAVerified bool `json:"amr"`
SessionID string `json:"sid"`
DeviceID string `json:"device_id,omitempty"`
IPAddress string `json:"ip_address,omitempty"`
}
// Token validation with comprehensive security checks
func (s *SecureAuthService) ValidateToken(ctx context.Context, tokenString string, clientIP string) (*AuthClaims, error) {
// Rate limiting check
if !s.rateLimiter.Allow(fmt.Sprintf("token_validation:%s", clientIP)) {
s.auditLogger.LogSecurityEvent("rate_limit_exceeded", "", clientIP, "warning", map[string]interface{}{
"operation": "token_validation",
})
return nil, fmt.Errorf("rate limit exceeded")
}
// Parse and validate JWT structure
token, err := jwt.ParseWithClaims(tokenString, &AuthClaims{}, func(token *jwt.Token) (interface{}, error) {
// Verify signing algorithm
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
// Get key ID from header
keyID, ok := token.Header["kid"].(string)
if !ok {
return nil, fmt.Errorf("missing key ID in token header")
}
// Retrieve public key
return s.keyStore.GetPublicKey(keyID)
})
if err != nil {
s.auditLogger.LogSecurityEvent("invalid_token", "", clientIP, "warning", map[string]interface{}{
"error": err.Error(),
})
return nil, fmt.Errorf("token validation failed: %w", err)
}
if !token.Valid {
return nil, fmt.Errorf("invalid token")
}
claims, ok := token.Claims.(*AuthClaims)
if !ok {
return nil, fmt.Errorf("invalid token claims")
}
// Additional security validations
if err := s.validateTokenClaims(claims, clientIP); err != nil {
s.auditLogger.LogSecurityEvent("token_validation_failed", claims.Subject, clientIP, "warning", map[string]interface{}{
"error": err.Error(),
})
return nil, err
}
// Check if session is still valid
if !s.sessionManager.IsValidSession(claims.SessionID, claims.Subject) {
s.auditLogger.LogSecurityEvent("invalid_session", claims.Subject, clientIP, "warning", map[string]interface{}{
"session_id": claims.SessionID,
})
return nil, fmt.Errorf("session no longer valid")
}
// Log successful validation
s.auditLogger.LogSecurityEvent("token_validated", claims.Subject, clientIP, "info", map[string]interface{}{
"session_id": claims.SessionID,
"roles": claims.Roles,
})
return claims, nil
}
func (s *SecureAuthService) validateTokenClaims(claims *AuthClaims, clientIP string) error {
now := time.Now()
// Check expiration
if claims.ExpiresAt != nil && claims.ExpiresAt.Time.Before(now) {
return fmt.Errorf("token expired")
}
// Check not before
if claims.NotBefore != nil && claims.NotBefore.Time.After(now) {
return fmt.Errorf("token not yet valid")
}
// Check issued at (prevent future tokens)
if claims.IssuedAt != nil && claims.IssuedAt.Time.After(now.Add(5*time.Minute)) {
return fmt.Errorf("token issued in the future")
}
// Validate audience
expectedAudience := "knowfoolery-quiz-game"
if !contains(claims.Audience, expectedAudience) {
return fmt.Errorf("invalid audience")
}
// Validate issuer
expectedIssuer := "https://auth.knowfoolery.com"
if claims.Issuer != expectedIssuer {
return fmt.Errorf("invalid issuer")
}
// IP address validation (if configured)
if claims.IPAddress != "" && claims.IPAddress != clientIP {
return fmt.Errorf("IP address mismatch")
}
return nil
}
// Multi-Factor Authentication enforcement
func (s *SecureAuthService) RequireMFA(userID string, roles []string) bool {
// Admin users always require MFA
for _, role := range roles {
if role == "admin" {
return true
}
}
// Check if user has high-value permissions
return s.hasHighValuePermissions(roles)
}
func (s *SecureAuthService) hasHighValuePermissions(roles []string) bool {
highValueRoles := []string{"moderator", "question_manager", "user_manager"}
for _, userRole := range roles {
for _, hvRole := range highValueRoles {
if userRole == hvRole {
return true
}
}
}
return false
}
```
### Player Authentication Flow (Web/Mobile)
```typescript
// Frontend authentication service

@ -23,6 +23,22 @@ Know Foolery is a quiz game inspired by the French game "Déconnaissance" (https
- **Leaderboard**: Display top 10 scores accessible to all players
- **Themes**: Questions are categorized by themes (Geography, History, Science, etc.)
### Documentation
#### Detailed requirements
- [Functional](1_requirements/functional-requirements.md)
- [Non Functional](1_requirements/non-functional-requirements.md)
#### Architecture
- [Technical](2_architecture/technical-architecture.md)
- [Security](2_architecture/security-architecture.md)
- [Observability](2_architecture/observability-architecture.md)
#### Guidelines
- [Development](3_guidelines/development-guidelines.md)
- [Security](3_guidelines/security-guidelines.md)
- [Observability](3_guidelines/observability-guidelines.md)
### Future Enhancements
#### Planned Features

@ -1,5 +0,0 @@
module knowfoolery
go 1.25.0
require github.com/stretchr/testify v1.10.0 // indirect

@ -1,2 +0,0 @@
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
Loading…
Cancel
Save