Guide for contributing and developing on Ackify.
- Go 1.24.5+
- Node.js 22+ and npm
- PostgreSQL 16+
- Docker & Docker Compose
- Git
# Clone
git clone https://github.com/kolapsis/ackify.git
cd ackify-ce
# Copy .env
cp .env.example .env
# Edit .env with your OAuth2 credentials
nano .envcd backend
go mod download
go build ./cmd/community# Start PostgreSQL with Docker
docker compose up -d ackify-db
# Apply migrations
go run ./cmd/migrate up
# Launch app
./communityAPI accessible at http://localhost:8080.
# 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# Format
go fmt ./...
# Vet
go vet ./...
# Staticcheck (optional)
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...cd webapp
npm installnpm run devFrontend accessible at http://localhost:5173 with Hot Module Replacement.
npm run build
# Output: webapp/dist/npm run type-checknpm run lint:i18nVerifies all translations are complete.
# 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# Shell in container
docker compose exec ackify-ce sh
# PostgreSQL shell
docker compose exec ackify-db psql -U ackifyr -d ackifybackend/
βββ 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
webapp/src/
βββ components/ # Vue components
βββ pages/ # Pages (router)
βββ services/ # API client
βββ stores/ # Pinia stores
βββ router/ # Vue Router
βββ locales/ # Translations
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")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 }
})- Define required API endpoints
- SQL schema if needed
- User interface
# 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# 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# Backend
# backend/internal/presentation/api/myfeature/handler_test.go
# Test
go test -v ./internal/presentation/api/myfeature/Update:
/api/openapi.yaml- OpenAPI specification/docs/api.md- API documentation/docs/features/my-feature.md- User guide
// Structured logs
logger.Info("signature created",
"doc_id", docID,
"user_sub", userSub,
"signature_id", sig.ID,
)
// Debug via Delve (optional)
dlv debug ./cmd/community// Vue DevTools (Chrome/Firefox extension)
// Inspect: Components, Pinia stores, Router
// Console debug
console.log('[DEBUG] User:', user.value)
// Breakpoints via browser
debugger-- 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;go run ./cmd/migrate upgo run ./cmd/migrate downdocker compose -f compose.test.yml up -dINTEGRATION_TESTS=1 go test -tags=integration -v ./internal/infrastructure/database/docker compose -f compose.test.yml down -vProject 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
# Install pre-commit
pip install pre-commit
# Setup hooks
pre-commit install
# Run manually
pre-commit run --all-files# 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 GitHubFormat: 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
Checklist:
- β Tests pass (CI green)
- β
Code formatted (
go fmt,eslint) - β No committed secrets
- β Documentation updated
- β Complete translations (i18n)
# Check PostgreSQL
docker compose ps ackify-db
docker compose logs ackify-db
# Check environment variables
cat .env
# Detailed logs
ACKIFY_LOG_LEVEL=debug ./community# Clean and reinstall
rm -rf node_modules package-lock.json
npm install
# Check Node version
node --version # Should be 22+# Backend - check PostgreSQL test
docker compose -f compose.test.yml ps
# Frontend - check types
npm run type-check