diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..e66f622 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,448 @@ + + +# 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 +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