Files
ackify/docs/en/development.md
2025-10-26 22:44:30 +01:00

514 lines
9.0 KiB
Markdown

# Development
Guide for contributing and developing on Ackify.
## Development Setup
### Prerequisites
- **Go 1.24.5+**
- **Node.js 22+** and npm
- **PostgreSQL 16+**
- **Docker & Docker Compose**
- Git
### Clone & Setup
```bash
# Clone
git clone https://github.com/btouchard/ackify-ce.git
cd ackify-ce
# Copy .env
cp .env.example .env
# Edit .env with your OAuth2 credentials
nano .env
```
## Backend Development
### Build
```bash
cd backend
go mod download
go build ./cmd/community
```
### Run
```bash
# Start PostgreSQL with Docker
docker compose up -d ackify-db
# Apply migrations
go run ./cmd/migrate up
# Launch app
./community
```
API accessible at `http://localhost:8080`.
### Tests
```bash
# Unit tests
go test -v -short ./...
# Tests with coverage
go test -coverprofile=coverage.out ./internal/... ./pkg/...
# View coverage
go tool cover -html=coverage.out
# Integration tests (PostgreSQL required)
docker compose -f ../compose.test.yml up -d
INTEGRATION_TESTS=1 go test -tags=integration -v ./internal/infrastructure/database/
docker compose -f ../compose.test.yml down
```
### Linting
```bash
# Format
go fmt ./...
# Vet
go vet ./...
# Staticcheck (optional)
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...
```
## Frontend Development
### Setup
```bash
cd webapp
npm install
```
### Dev Server
```bash
npm run dev
```
Frontend accessible at `http://localhost:5173` with Hot Module Replacement.
### Production Build
```bash
npm run build
# Output: webapp/dist/
```
### Type Checking
```bash
npm run type-check
```
### i18n Validation
```bash
npm run lint:i18n
```
Verifies all translations are complete.
## Docker Development
### Local Build
```bash
# Build complete image (frontend + backend)
docker compose -f compose.local.yml up -d --build
# Logs
docker compose -f compose.local.yml logs -f ackify-ce
# Rebuild after changes
docker compose -f compose.local.yml up -d --force-recreate ackify-ce --build
```
### Debug
```bash
# Shell in container
docker compose exec ackify-ce sh
# PostgreSQL shell
docker compose exec ackify-db psql -U ackifyr -d ackify
```
## Code Structure
### Backend
```
backend/
├── cmd/
│ ├── community/ # main.go + dependency injection
│ └── migrate/ # Migration tool
├── internal/
│ ├── domain/models/ # Entities (User, Signature, Document)
│ ├── application/services/ # Business logic
│ ├── infrastructure/
│ │ ├── auth/ # OAuth2
│ │ ├── database/ # Repositories
│ │ ├── email/ # SMTP
│ │ └── config/ # Config
│ └── presentation/api/ # HTTP handlers
└── pkg/ # Utilities
```
### Frontend
```
webapp/src/
├── components/ # Vue components
├── pages/ # Pages (router)
├── services/ # API client
├── stores/ # Pinia stores
├── router/ # Vue Router
└── locales/ # Translations
```
## Code Conventions
### Go
**Naming**:
- Packages: lowercase, singular (`user`, `signature`)
- Interfaces: suffix `er` or descriptive (`SignatureRepository`, `EmailSender`)
- Constructors: `New...()` or `...From...()`
**Example**:
```go
// Service
type SignatureService struct {
repo SignatureRepository
crypto CryptoService
}
func NewSignatureService(repo SignatureRepository, crypto CryptoService) *SignatureService {
return &SignatureService{repo: repo, crypto: crypto}
}
// Method
func (s *SignatureService) CreateSignature(ctx context.Context, docID, userSub string) (*models.Signature, error) {
// ...
}
```
**Errors**:
```go
// Wrapping
return nil, fmt.Errorf("failed to create signature: %w", err)
// Custom errors
var ErrAlreadySigned = errors.New("user has already signed this document")
```
### TypeScript
**Naming**:
- Components: PascalCase (`DocumentCard.vue`)
- Composables: camelCase with `use` prefix (`useAuth.ts`)
- Stores: camelCase with `Store` suffix (`userStore.ts`)
**Example**:
```typescript
// Composable
export function useAuth() {
const user = ref<User | null>(null)
async function login() {
// ...
}
return { user, login }
}
// Store
export const useUserStore = defineStore('user', () => {
const currentUser = ref<User | null>(null)
async function fetchMe() {
const { data } = await api.get('/users/me')
currentUser.value = data
}
return { currentUser, fetchMe }
})
```
## Adding a Feature
### 1. Planning
- Define required API endpoints
- SQL schema if needed
- User interface
### 2. Backend
```bash
# 1. Create migration if needed
touch backend/migrations/XXXX_my_feature.up.sql
touch backend/migrations/XXXX_my_feature.down.sql
# 2. Create model
# backend/internal/domain/models/my_model.go
# 3. Create repository interface
# backend/internal/application/services/my_service.go
# 4. Implement repository
# backend/internal/infrastructure/database/my_repository.go
# 5. Create API handler
# backend/internal/presentation/api/myfeature/handler.go
# 6. Register routes
# backend/internal/presentation/api/router.go
```
### 3. Frontend
```bash
# 1. Create API service
# webapp/src/services/myFeatureService.ts
# 2. Create Pinia store
# webapp/src/stores/myFeatureStore.ts
# 3. Create components
# webapp/src/components/MyFeature.vue
# 4. Add translations
# webapp/src/locales/{fr,en,es,de,it}.json
# 5. Add routes if needed
# webapp/src/router/index.ts
```
### 4. Tests
```bash
# Backend
# backend/internal/presentation/api/myfeature/handler_test.go
# Test
go test -v ./internal/presentation/api/myfeature/
```
### 5. Documentation
Update:
- `/api/openapi.yaml` - OpenAPI specification
- `/docs/api.md` - API documentation
- `/docs/features/my-feature.md` - User guide
## Debugging
### Backend
```go
// Structured logs
logger.Info("signature created",
"doc_id", docID,
"user_sub", userSub,
"signature_id", sig.ID,
)
// Debug via Delve (optional)
dlv debug ./cmd/community
```
### Frontend
```typescript
// Vue DevTools (Chrome/Firefox extension)
// Inspect: Components, Pinia stores, Router
// Console debug
console.log('[DEBUG] User:', user.value)
// Breakpoints via browser
debugger
```
## SQL Migrations
### Create Migration
```sql
-- XXXX_add_field.up.sql
ALTER TABLE signatures ADD COLUMN new_field TEXT;
-- XXXX_add_field.down.sql
ALTER TABLE signatures DROP COLUMN new_field;
```
### Apply
```bash
go run ./cmd/migrate up
```
### Rollback
```bash
go run ./cmd/migrate down
```
## Integration Tests
### Setup PostgreSQL Test
```bash
docker compose -f compose.test.yml up -d
```
### Run Tests
```bash
INTEGRATION_TESTS=1 go test -tags=integration -v ./internal/infrastructure/database/
```
### Cleanup
```bash
docker compose -f compose.test.yml down -v
```
## CI/CD
### GitHub Actions
Project uses `.github/workflows/ci.yml`:
**Jobs**:
1. **Lint** - go fmt, go vet, eslint
2. **Test Backend** - Unit + integration tests
3. **Test Frontend** - Type checking + i18n validation
4. **Coverage** - Upload to Codecov
5. **Build** - Verify Docker image builds
### Pre-commit Hooks (optional)
```bash
# Install pre-commit
pip install pre-commit
# Setup hooks
pre-commit install
# Run manually
pre-commit run --all-files
```
## Contribution
### Git Workflow
```bash
# 1. Create branch
git checkout -b feature/my-feature
# 2. Develop + commit
git add .
git commit -m "feat: add my feature"
# 3. Push
git push origin feature/my-feature
# 4. Create Pull Request on GitHub
```
### Commit Messages
Format: `type: description`
**Types**:
- `feat` - New feature
- `fix` - Bug fix
- `docs` - Documentation
- `refactor` - Refactoring
- `test` - Tests
- `chore` - Maintenance
**Examples**:
```
feat: add checksum verification feature
fix: resolve OAuth callback redirect loop
docs: update API documentation for signatures
refactor: simplify signature service logic
test: add integration tests for expected signers
```
### Code Review
**Checklist**:
- ✅ Tests pass (CI green)
- ✅ Code formatted (`go fmt`, `eslint`)
- ✅ No committed secrets
- ✅ Documentation updated
- ✅ Complete translations (i18n)
## Troubleshooting
### Backend won't start
```bash
# Check PostgreSQL
docker compose ps ackify-db
docker compose logs ackify-db
# Check environment variables
cat .env
# Detailed logs
ACKIFY_LOG_LEVEL=debug ./community
```
### Frontend build fails
```bash
# Clean and reinstall
rm -rf node_modules package-lock.json
npm install
# Check Node version
node --version # Should be 22+
```
### Tests fail
```bash
# Backend - check PostgreSQL test
docker compose -f compose.test.yml ps
# Frontend - check types
npm run type-check
```
## Resources
- [Go Documentation](https://go.dev/doc/)
- [Vue 3 Guide](https://vuejs.org/guide/)
- [PostgreSQL Docs](https://www.postgresql.org/docs/)
- [Chi Router](https://github.com/go-chi/chi)
- [Pinia](https://pinia.vuejs.org/)
## Support
- [GitHub Issues](https://github.com/btouchard/ackify-ce/issues)
- [GitHub Discussions](https://github.com/btouchard/ackify-ce/discussions)