Technical stack and design principles of Ackify.
Ackify is a modern monolithic application with clear backend/frontend separation.
βββββββββββββββββββββββββββββββββββββββββββ
β Client Browser β
β (Vue.js 3 SPA + TypeScript) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β HTTPS / JSON
ββββββββββββββββΌβββββββββββββββββββββββββββ
β Go Backend (API-first) β
β ββ RESTful API v1 (chi router) β
β ββ OAuth2 Service β
β ββ Ed25519 Crypto β
β ββ SMTP Email (optional) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β PostgreSQL protocol
ββββββββββββββββΌβββββββββββββββββββββββββββ
β PostgreSQL 16 Database β
β (Signatures + Metadata + Sessions) β
βββββββββββββββββββββββββββββββββββββββββββ
backend/
βββ cmd/
β βββ community/ # Entry point + dependency injection
β βββ migrate/ # SQL migrations tool
βββ internal/
β βββ domain/
β β βββ models/ # Business entities (User, Signature, Document)
β βββ application/
β β βββ services/ # Business logic (SignatureService, etc.)
β βββ infrastructure/
β β βββ auth/ # OAuth2 service
β β βββ database/ # PostgreSQL repositories
β β βββ email/ # SMTP service
β β βββ config/ # Environment variables
β β βββ i18n/ # Backend i18n
β βββ presentation/
β βββ api/ # HTTP handlers API v1
β βββ handlers/ # Legacy OAuth handlers
βββ pkg/
β βββ crypto/ # Ed25519 signatures
β βββ logger/ # Structured logging
β βββ services/ # OAuth provider detection
β βββ web/ # HTTP server setup
βββ migrations/ # SQL migrations
βββ templates/ # Email templates (HTML/text)
βββ locales/ # Backend translations
Interfaces:
- β Defined in the package that uses them
- β Principle "accept interfaces, return structs"
- β
Repositories implemented in
infrastructure/database/
Dependency Injection:
- β
Explicit constructors in
main.go - β No complex DI container
- β Clear and visible dependencies
Code Quality:
- β
go fmtandgo vetclean - β No dead code
- β Simple and focused interfaces
webapp/
βββ src/
β βββ components/ # Reusable components
β β βββ ui/ # shadcn/vue components
β β βββ ...
β βββ pages/ # Pages (router views)
β β βββ Home.vue
β β βββ Admin.vue
β β βββ ...
β βββ services/ # API client (axios)
β βββ stores/ # Pinia state management
β βββ router/ # Vue Router config
β βββ locales/ # Translations (fr, en, es, de, it)
β βββ composables/ # Vue composables
βββ public/ # Static assets
βββ scripts/ # Build scripts
- Vue 3 - Composition API
- TypeScript - Type safety
- Vite - Build tool (fast HMR)
- Pinia - State management
- Vue Router - Client routing
- Tailwind CSS - Utility-first styling
- shadcn/vue - UI components
- vue-i18n - Internationalization
const routes = [
{ path: '/', component: Home }, // Public
{ path: '/signatures', component: MySignatures }, // Auth required
{ path: '/admin', component: Admin } // Admin only
]Frontend handles:
- Route
/with query param?doc=xxxβ Signature page - Route
/adminβ Admin dashboard - Route
/signaturesβ My signatures
Main tables:
signatures- Ed25519 signaturesdocuments- Document metadataexpected_signers- Signer trackingreminder_logs- Email historychecksum_verifications- Integrity verificationsoauth_sessions- OAuth2 sessions + refresh tokens
See Database for complete schema.
- Format:
XXXX_description.up.sql/XXXX_description.down.sql - Applied automatically on startup (service
ackify-migrate) - Tool:
/backend/cmd/migrate
Ed25519:
- Digital signatures (elliptic curve)
- 256-bit private key
- Guaranteed non-repudiation
SHA-256:
- Payload hashing before signing
- Tampering detection
- Blockchain-like chaining (
prev_hash)
AES-256-GCM:
- OAuth2 refresh token encryption
- Key derived from
ACKIFY_OAUTH_COOKIE_SECRET
Flow:
- Client generates
code_verifier(random) - Calculates
code_challenge = SHA256(code_verifier) - Auth request with
code_challenge - Provider returns
code - Token exchange with
code + code_verifier
Security:
- Protection against code interception
- S256 method (SHA-256)
- Automatically enabled
- Secure cookies (HttpOnly, Secure, SameSite=Lax)
- HMAC-SHA256 encryption
- PostgreSQL storage with encrypted refresh tokens
- Duration: 30 days
- Automatic cleanup: 37 days
# Stage 1 - Frontend build
FROM node:22-alpine AS frontend
COPY webapp/ /build/webapp/
RUN npm ci && npm run build
# Output: webapp/dist/
# Stage 2 - Backend build + embed frontend
FROM golang:alpine AS backend
ENV GOTOOLCHAIN=auto
COPY backend/ /build/backend/
COPY --from=frontend /build/webapp/dist/ /build/backend/cmd/community/web/dist/
RUN go build -o community ./cmd/community
# Frontend embedded via embed.FS
# Stage 3 - Runtime (distroless)
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=backend /build/backend/community /app/community
CMD ["/app/community"]Result:
- Final image < 30 MB
- Single binary (backend + frontend)
- No runtime dependencies
ACKIFY_BASE_URL is injected into index.html at startup:
// Replaces __ACKIFY_BASE_URL__ with actual value
html = strings.ReplaceAll(html, "__ACKIFY_BASE_URL__", baseURL)Allows changing domain without rebuild.
- Connection pooling PostgreSQL (25 max)
- Prepared statements - SQL injection prevention
- Rate limiting - 5 auth/min, 10 doc/min, 100 req/min
- Structured logging - JSON with request IDs
- Code splitting - Lazy loading routes
- Tree shaking - Dead code elimination
- Minification - Optimized production builds
- HMR - Hot Module Replacement (dev)
- Indexes on (doc_id, user_sub, session_id)
- Constraints UNIQUE for guarantees
- Triggers for immutability
- Autovacuum enabled
- β Monolith: ~10k req/s
- β PostgreSQL: Single instance
- β Sessions: In-database (no Redis)
For > 100k req/s:
- Load Balancer - Multiple backend instances
- PostgreSQL read replicas - Separate read/write
- Redis - Session cache + rate limiting
- CDN - Static assets
JSON format:
{
"level": "info",
"timestamp": "2025-01-15T14:30:00Z",
"request_id": "abc123",
"method": "POST",
"path": "/api/v1/signatures",
"duration_ms": 42,
"status": 201
}GET /api/v1/healthResponse:
{
"status": "healthy",
"database": "connected"
}- Prometheus metrics endpoint
- Grafana dashboards
- Alerting (PagerDuty, Slack)
72.6% code coverage (unit + integration)
- Unit tests: 180+ tests
- Integration tests: 33 PostgreSQL tests
- CI/CD: GitHub Actions + Codecov
See Development to run tests.
- β Native performance (compiled)
- β Simple concurrency (goroutines)
- β Strong typing
- β Single binary
- β Simple deployment
- β Modern Composition API
- β Native TypeScript
- β Reactive by default
- β Rich ecosystem
- β Excellent performance
- β ACID compliance
- β Integrity constraints
- β Triggers
- β JSON support
- β Mature and stable
- β Modern security (elliptic curve)
- β Performance > RSA
- β Short signatures (64 bytes)
- β Standard crypto/ed25519 Go