mirror of
https://github.com/btouchard/ackify.git
synced 2026-01-04 03:49:38 -06:00
9.0 KiB
9.0 KiB
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
# 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
cd backend
go mod download
go build ./cmd/community
Run
# 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
# 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
# Format
go fmt ./...
# Vet
go vet ./...
# Staticcheck (optional)
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...
Frontend Development
Setup
cd webapp
npm install
Dev Server
npm run dev
Frontend accessible at http://localhost:5173 with Hot Module Replacement.
Production Build
npm run build
# Output: webapp/dist/
Type Checking
npm run type-check
i18n Validation
npm run lint:i18n
Verifies all translations are complete.
Docker Development
Local Build
# 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
# 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
eror descriptive (SignatureRepository,EmailSender) - Constructors:
New...()or...From...()
Example:
// 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:
// 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
useprefix (useAuth.ts) - Stores: camelCase with
Storesuffix (userStore.ts)
Example:
// 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
# 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
# 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
# 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
// 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
// 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
-- 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
go run ./cmd/migrate up
Rollback
go run ./cmd/migrate down
Integration Tests
Setup PostgreSQL Test
docker compose -f compose.test.yml up -d
Run Tests
INTEGRATION_TESTS=1 go test -tags=integration -v ./internal/infrastructure/database/
Cleanup
docker compose -f compose.test.yml down -v
CI/CD
GitHub Actions
Project uses .github/workflows/ci.yml:
Jobs:
- Lint - go fmt, go vet, eslint
- Test Backend - Unit + integration tests
- Test Frontend - Type checking + i18n validation
- Coverage - Upload to Codecov
- Build - Verify Docker image builds
Pre-commit Hooks (optional)
# Install pre-commit
pip install pre-commit
# Setup hooks
pre-commit install
# Run manually
pre-commit run --all-files
Contribution
Git Workflow
# 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 featurefix- Bug fixdocs- Documentationrefactor- Refactoringtest- Testschore- 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
# 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
# Clean and reinstall
rm -rf node_modules package-lock.json
npm install
# Check Node version
node --version # Should be 22+
Tests fail
# Backend - check PostgreSQL test
docker compose -f compose.test.yml ps
# Frontend - check types
npm run type-check