- Document frontend and backend tech stacks - Describe component hierarchy and routing - Explain state management with React Context - Document API endpoints and database schema - Include authentication modes (simple/Keycloak) - Describe design patterns used - Document testing architecture
13 KiB
Architecture Documentation
Overview
kilo-cv is a full-stack web application for managing and displaying a professional CV/resume. It features a public-facing CV display page and an authenticated admin panel for content management.
Key Features
- Public CV Display: Responsive, animated CV page with sections for experience, skills, education, and projects
- Admin Panel: Authenticated interface for editing CV content
- REST API: Backend API for data management
- Export/Import: JSON export and import functionality
- API Documentation: Interactive Swagger UI
Technology Stack
Frontend
| Technology | Version | Purpose |
|---|---|---|
| React | 19.x | UI library |
| Vite | 7.x | Build tool and dev server |
| Tailwind CSS | 4.x | Styling |
| Framer Motion | 12.x | Animations |
| Lucide React | 0.574.x | Icon library |
| React Router DOM | 7.x | Client-side routing |
Backend
| Technology | Version | Purpose |
|---|---|---|
| Express.js | 4.x | REST API server |
| Knex.js | 3.x | SQL query builder |
| better-sqlite3 | 11.x | SQLite database driver |
| swagger-jsdoc | 6.x | OpenAPI documentation generation |
| swagger-ui-express | 5.x | Swagger UI serving |
Directory Structure
kilo-cv/
├── src/ # Frontend source
│ ├── components/ # Public CV display components
│ │ ├── Hero.jsx # Name, title, introduction
│ │ ├── Experience.jsx # Work history section
│ │ ├── Skills.jsx # Skills by category
│ │ ├── Education.jsx # Education history
│ │ ├── Projects.jsx # Project showcase
│ │ └── Contact.jsx # Contact information
│ ├── admin/ # Admin panel
│ │ ├── AdminLayout.jsx # Admin layout with navigation
│ │ ├── AdminPersonal.jsx # Personal info editor
│ │ ├── AdminExperience.jsx # Experience editor
│ │ ├── AdminSkills.jsx # Skills editor
│ │ ├── AdminEducation.jsx # Education editor
│ │ ├── AdminProjects.jsx # Projects editor
│ │ ├── pages/
│ │ │ └── LoginPage.jsx # Authentication page
│ │ ├── sections/ # Reusable form components
│ │ │ ├── PersonalForm.jsx
│ │ │ ├── ExperienceForm.jsx
│ │ │ ├── SkillsForm.jsx
│ │ │ ├── EducationForm.jsx
│ │ │ └── ProjectsForm.jsx
│ │ ├── hooks/ # React contexts and custom hooks
│ │ │ ├── CVContext.jsx # CV data state management
│ │ │ ├── AuthContext.jsx # Authentication state
│ │ │ ├── useCVData.js # CV data access hook
│ │ │ └── useFormValidation.js
│ │ └── components/
│ │ └── ExportButton.jsx
│ ├── lib/ # Utilities and API client
│ │ ├── api.js # API client functions
│ │ ├── auth.js # Token management
│ │ ├── cv-data.js # CV validation utilities
│ │ └── cv.json # Default CV data structure
│ ├── data/
│ │ └── cv.js
│ ├── App.jsx # Root component with routing
│ ├── main.jsx # React entry point
│ └── index.css # Global styles (Tailwind)
├── backend/ # Backend source
│ ├── routes/ # API route handlers
│ │ ├── cv.js # CV CRUD endpoints
│ │ ├── auth.js # Authentication endpoints
│ │ └── docs.js # Swagger documentation route
│ ├── db/
│ │ └── init.js # Database initialization
│ ├── migrations/
│ │ └── 20260220000001_initial_schema.js
│ ├── middleware/
│ │ └── auth.js # JWT authentication middleware
│ ├── seeds/
│ │ └── initial_cv_data.js # Initial data seeding
│ ├── __tests__/
│ │ └── api.test.js # API tests
│ ├── server.js # Express server entry point
│ └── knexfile.js # Knex configuration
├── tests/ # Test suites
│ ├── e2e/ # Playwright E2E tests
│ ├── integration/ # Integration tests
│ ├── regression/ # Snapshot/regression tests
│ └── performance/ # k6 and Lighthouse tests
├── docs/ # Documentation
├── public/ # Static assets
└── .github/ # CI/CD workflows
Frontend Architecture
Routing Structure
/ → Public CV display
/admin → Admin panel (requires auth)
/admin/login → Login page
/admin/personal → Personal info editor
/admin/experience → Experience editor
/admin/skills → Skills editor
/admin/education → Education editor
/admin/projects → Projects editor
Component Hierarchy
App
├── CVProvider (context)
│ └── AuthProvider (context)
│ ├── Routes
│ │ ├── "/" → CV Display Page
│ │ │ └── Hero, Experience, Skills, Education, Projects, Contact
│ │ └── "/admin/*" → AdminLayout
│ │ ├── LoginPage (unauthenticated)
│ │ └── Admin* Pages (authenticated)
│ │ └── *Form components
State Management
The application uses React Context for state management:
CVContext (src/admin/hooks/CVContext.jsx)
- Manages CV data state
- Provides
useCVData()hook for components - Handles API communication for CRUD operations
AuthContext (src/admin/hooks/AuthContext.jsx)
- Manages authentication state
- Handles token storage and validation
- Provides
useAuth()hook for protected routes
Custom Hooks
| Hook | Purpose |
|---|---|
useCVData() |
Access CV data and CRUD operations |
useAuth() |
Access authentication state and methods |
useFormValidation() |
Form validation with error handling |
Styling
- Tailwind CSS 4 with
@tailwindcss/viteplugin - Utility-first approach throughout
- Responsive design with mobile-first breakpoints
- Animations via Framer Motion
Backend Architecture
API Endpoints
| Endpoint | Method | Description | Auth |
|---|---|---|---|
/api/auth/config |
GET | Get auth configuration | No |
/api/auth/login |
POST | Authenticate with password | No |
/api/cv |
GET | Get CV data | No |
/api/cv |
PUT | Update CV data | Yes |
/api/cv/export |
GET | Export CV as JSON | No |
/api/cv/import |
POST | Import CV from JSON | Yes |
/api/docs |
GET | Swagger UI documentation | No |
/health |
GET | Health check endpoint | No |
Request/Response Examples
Get CV Data
GET /api/cv
Response: {
"personal": { "name": "...", "title": "...", ... },
"experience": [...],
"skills": {...},
"education": [...],
"projects": [...]
}
Update CV Data
PUT /api/cv
Authorization: Bearer <token>
Body: { "personal": {...}, "experience": [...], ... }
Response: { "success": true }
Login
POST /api/auth/login
Body: { "password": "..." }
Response: { "token": "..." }
Database Schema
Single-table design for simplicity:
CREATE TABLE cv_data (
id INTEGER PRIMARY KEY CHECK (id = 1),
data TEXT NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
The CV data is stored as a JSON document in the data column:
{
"personal": {
"name": "string",
"title": "string",
"intro": "string",
"email": "string",
"github": "string",
"linkedin": "string",
"location": "string"
},
"experience": [
{
"company": "string",
"position": "string",
"startDate": "YYYY-MM",
"endDate": "YYYY-MM or null",
"description": "string",
"highlights": ["string", ...]
}
],
"skills": {
"Category Name": ["skill1", "skill2", ...]
},
"education": [
{
"institution": "string",
"degree": "string",
"field": "string",
"startDate": "YYYY",
"endDate": "YYYY"
}
],
"projects": [
{
"name": "string",
"description": "string",
"technologies": ["tech1", ...],
"url": "string"
}
]
}
Authentication
Two authentication modes are supported:
Simple Mode (default)
- Random password generated on server startup
- Password logged to console
- JWT token-based authentication
- Suitable for personal/single-user deployments
Keycloak Mode (optional)
- SSO integration via Keycloak
- Configure via environment variables
- Suitable for enterprise deployments
Environment variables for Keycloak:
AUTH_MODE=keycloak
KEYCLOAK_URL=https://keycloak.example.com
KEYCLOAK_REALM=your-realm
KEYCLOAK_CLIENT_ID=cv-app
Middleware
Auth Middleware (backend/middleware/auth.js)
- Validates JWT token from Authorization header
- Attaches user info to request
- Returns 401 for invalid/missing tokens
Design Patterns
Frontend Patterns
-
Context Provider Pattern
CVProviderandAuthProviderwrap the application- Provides global state without prop drilling
-
Custom Hook Pattern
useCVData(),useAuth()expose context values- Encapsulates complex logic
-
Container/Presentational Pattern
- Admin pages fetch data from context (container)
- Form components handle UI (presentational)
-
Form Validation Pattern
useFormValidationhook provides reusable validation- Error state management standardized
Backend Patterns
-
Route Handler Pattern
- Modular Express routers in
/routes - Clean separation of concerns
- Modular Express routers in
-
Middleware Pattern
- Auth middleware for protected routes
- Composable request processing
-
Repository Pattern
getDB()returns Knex instance- Database access abstracted from route handlers
-
Migration-based Schema
- Knex migrations for version control
- Rollback capability
Testing Architecture
| Layer | Tool | Location | Purpose |
|---|---|---|---|
| Unit | Vitest | src/lib/__tests__/, src/admin/hooks/__tests__/ |
Test utilities and hooks |
| API | Vitest + Supertest | backend/__tests__/ |
Test API endpoints |
| Integration | Vitest | tests/integration/ |
Test full-stack interactions |
| E2E | Playwright | tests/e2e/ |
Test user flows |
| Regression | Vitest | tests/regression/ |
Snapshot tests |
| Performance | k6, Lighthouse | tests/performance/ |
Load and performance testing |
Test Commands
npm run test:run # Run unit tests
npm run test:coverage # Run tests with coverage
npm run test:integration # Run integration tests
npm run test:e2e # Run E2E tests (requires running server)
npm run test:regression # Run regression tests
Configuration
Frontend Configuration
Vite (vite.config.js)
- React plugin with SWC
- Tailwind CSS plugin
- Proxy configuration for API
Tailwind (src/index.css)
- Tailwind imports
- Custom CSS variables
Backend Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT |
3001 | Server port |
AUTH_MODE |
simple | Authentication mode (simple/keycloak) |
KEYCLOAK_URL |
- | Keycloak server URL |
KEYCLOAK_REALM |
- | Keycloak realm |
KEYCLOAK_CLIENT_ID |
- | Keycloak client ID |
Knex (backend/knexfile.js)
- SQLite database configuration
- Migration and seed directories
Development
Prerequisites
- Node.js 20+
- npm 10+
Getting Started
# Install frontend dependencies
npm install
# Install backend dependencies
cd backend && npm install
# Start backend server
npm run dev:backend
# In another terminal, start frontend
npm run dev
Build
# Build frontend
npm run build
# Build outputs to dist/
Docker
# Build and run with Docker Compose
docker-compose up --build
The Docker setup includes:
- Frontend container with nginx
- Backend container with Node.js
- SQLite volume for persistence
Security Considerations
- Authentication: JWT tokens with configurable expiration
- Secret Scanning: Gitleaks pre-commit hook
- Input Validation: Form validation on frontend, schema validation on backend
- CORS: Configured for frontend origin
- SQL Injection: Knex query builder prevents injection
Future Considerations
- Image Upload: Profile picture support
- PDF Export: Generate PDF from CV data
- Themes: Customizable color schemes
- Multi-language: Internationalization support
- Analytics: View tracking for CV