docs: add architecture documentation
- 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
This commit is contained in:
448
docs/architecture.md
Normal file
448
docs/architecture.md
Normal file
@@ -0,0 +1,448 @@
|
||||
<!-- markdownlint-disable MD013 -->
|
||||
|
||||
# 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/vite` plugin
|
||||
- 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**
|
||||
```http
|
||||
GET /api/cv
|
||||
Response: {
|
||||
"personal": { "name": "...", "title": "...", ... },
|
||||
"experience": [...],
|
||||
"skills": {...},
|
||||
"education": [...],
|
||||
"projects": [...]
|
||||
}
|
||||
```
|
||||
|
||||
**Update CV Data**
|
||||
```http
|
||||
PUT /api/cv
|
||||
Authorization: Bearer <token>
|
||||
Body: { "personal": {...}, "experience": [...], ... }
|
||||
Response: { "success": true }
|
||||
```
|
||||
|
||||
**Login**
|
||||
```http
|
||||
POST /api/auth/login
|
||||
Body: { "password": "..." }
|
||||
Response: { "token": "..." }
|
||||
```
|
||||
|
||||
### Database Schema
|
||||
|
||||
Single-table design for simplicity:
|
||||
|
||||
```sql
|
||||
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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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:
|
||||
```bash
|
||||
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
|
||||
|
||||
1. **Context Provider Pattern**
|
||||
- `CVProvider` and `AuthProvider` wrap the application
|
||||
- Provides global state without prop drilling
|
||||
|
||||
2. **Custom Hook Pattern**
|
||||
- `useCVData()`, `useAuth()` expose context values
|
||||
- Encapsulates complex logic
|
||||
|
||||
3. **Container/Presentational Pattern**
|
||||
- Admin pages fetch data from context (container)
|
||||
- Form components handle UI (presentational)
|
||||
|
||||
4. **Form Validation Pattern**
|
||||
- `useFormValidation` hook provides reusable validation
|
||||
- Error state management standardized
|
||||
|
||||
### Backend Patterns
|
||||
|
||||
1. **Route Handler Pattern**
|
||||
- Modular Express routers in `/routes`
|
||||
- Clean separation of concerns
|
||||
|
||||
2. **Middleware Pattern**
|
||||
- Auth middleware for protected routes
|
||||
- Composable request processing
|
||||
|
||||
3. **Repository Pattern**
|
||||
- `getDB()` returns Knex instance
|
||||
- Database access abstracted from route handlers
|
||||
|
||||
4. **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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# Build frontend
|
||||
npm run build
|
||||
|
||||
# Build outputs to dist/
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
1. **Authentication**: JWT tokens with configurable expiration
|
||||
2. **Secret Scanning**: Gitleaks pre-commit hook
|
||||
3. **Input Validation**: Form validation on frontend, schema validation on backend
|
||||
4. **CORS**: Configured for frontend origin
|
||||
5. **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
|
||||
Reference in New Issue
Block a user