# 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(null) async function login() { // ... } return { user, login } } // Store export const useUserStore = defineStore('user', () => { const currentUser = ref(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)