first commit

This commit is contained in:
2025-12-02 21:26:08 +01:00
commit 790f4a9f1d
23 changed files with 4085 additions and 0 deletions
+312
View File
@@ -0,0 +1,312 @@
# ZynkTime
A time reporting application for the Kleer API with both FastAPI web interface and CLI.
## Features
- 🎨 **Modern Web UI**: Beautiful, responsive web interface with drag-and-drop file upload
- 📊 **CSV Processing**: Parse and extract work time from CSV files
- 🌐 **REST API**: FastAPI endpoints for time reporting
- 💻 **CLI Interface**: Interactive command-line time reporting
-**Input Validation**: Pydantic models for data validation
- 🧪 **Tested**: Unit tests with pytest
- 📝 **Well-Documented**: Comprehensive docstrings and type hints
## Quick Start
### 🐳 Docker (Recommended)
The easiest way to run ZynkTime is with Docker:
```bash
# 1. Clone the repository
cd zynktime
# 2. Copy environment file
cp .env.example .env
# 3. Edit .env and add your API key
nano .env # or use your favorite editor
# 4. Start with Docker Compose
docker-compose up -d
# 5. Open your browser
# Navigate to: http://localhost:8000
```
**Docker Commands:**
```bash
# Start the application
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the application
docker-compose down
# Rebuild after code changes
docker-compose up -d --build
# Access container shell
docker-compose exec zynktime bash
```
### 🐍 Manual Installation
If you prefer to run without Docker:
```bash
# Clone the repository
cd zynktime
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
```
### Configuration
**Option 1: Environment File (Recommended)**
```bash
# Copy example file
cp .env.example .env
# Edit with your values
nano .env
```
**Option 2: Export Variables**
```bash
export KLEER_API_KEY="your_api_key_here"
export KLEER_USERNAME="Your Name" # Optional, defaults to "Christopher Juhlin"
export KLEER_COMPANY_ID="1336" # Optional, defaults to "1336"
```
### Running the Application
**Web UI Mode (Recommended):**
```bash
python main.py
# Open your browser and navigate to: http://localhost:8000
```
**CLI Mode:**
```bash
python main.py cli
# Interactive CLI for processing CSV files
```
### Using the Web UI
1. **Open your browser** to `http://localhost:8000`
2. **Upload your CSV file** by dragging and dropping or clicking to browse
3. **Select a project** from the dropdown
4. **Click "Report Time"** to submit
5. View the **results summary** with total hours and days reported
The web interface features:
- 🎯 Drag-and-drop file upload
- 📋 Real-time project list
- 💫 Smooth animations and transitions
- 📱 Fully responsive design
- 🔔 Toast notifications for feedback
- ✅ Connection status indicator
## API Endpoints
### GET /
Serves the modern web UI interface.
### GET /api
Returns API information and available endpoints.
### GET /health
Health check endpoint - verifies API key configuration.
**Response:**
```json
{
"status": "healthy",
"api_key_configured": true
}
```
### GET /projects
Lists all active projects for the configured user.
**Response:**
```json
{
"Project Name": {
"id": 123,
"activity": {"id": 456}
}
}
```
### POST /report-time
Upload a CSV file and report time to a specific project.
**Parameters:**
- `project_name` (query): Name of the project
- `file` (form): CSV file with time entries
**Response:**
```json
{
"message": "Time reported successfully.",
"reported_days": 5,
"total_hours": 40.0,
"project_name": "Project Name",
"user_name": "Your Name"
}
```
### GET /docs
Interactive API documentation (Swagger UI).
## CSV Format
The application **automatically detects** the CSV delimiter (comma or semicolon) and column structure.
### Supported Formats
**Format 1: Comma-separated with headers**
```csv
reg_period,xreg_period,T,Time code,Time code (T),Vouch.date,Project Activity,Project Activity (T),Work package,Work package (T),Hours,Workflow status,Text
202544,,A,0,Standard Time,10/27/2025,,,,,2.00,N,
202544,,A,0,Standard Time,10/28/2025,,,,,4.00,N,
```
**Format 2: Semicolon-separated**
```csv
...;...;...;...;...;01/15/2024;...;...;...;...;8.5;...
...;...;...;...;...;01/16/2024;...;...;...;...;7,5;...
```
### Column Detection
- **Date column**: Automatically detected by searching for columns containing "date" or "vouch" in the header
- **Hours column**: Automatically detected by searching for columns containing "hour" in the header
- **Date formats**: Supports both `MM/DD/YYYY` and `YYYY-MM-DD`
- **Hours format**: Supports decimal hours with comma (`,`) or dot (`.`) as separator
- **Whitespace**: Automatically trimmed from values
## Development
### Project Structure
```
zynktime/
├── static/
│ ├── index.html # Modern web UI
│ ├── css/
│ │ └── style.css # Responsive styling
│ └── js/
│ └── app.js # Frontend logic
├── main.py # FastAPI application entry point
├── cli.py # CLI interface
├── config.py # Configuration management
├── models.py # Pydantic models
├── api_client.py # Kleer API client
├── services.py # Business logic
├── test_main.py # Unit tests
├── requirements.txt # Python dependencies
├── AGENTS.md # Guidelines for AI agents
└── README.md # This file
```
### Running Tests
```bash
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific test
pytest test_main.py::TestServices::test_validate_date_valid -v
# Run with coverage
pytest --cov=. --cov-report=html
```
### Code Quality
The codebase follows:
- **Type hints**: Full typing support
- **Error handling**: Specific exceptions with proper logging
- **Separation of concerns**: Modular architecture
- **Documentation**: Comprehensive docstrings
- **Testing**: Unit tests for core functionality
## Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `KLEER_API_KEY` | Yes | - | API key for Kleer API |
| `KLEER_USERNAME` | No | Christopher Juhlin | Username for API requests |
| `KLEER_COMPANY_ID` | No | 1336 | Company ID for API requests |
## Docker Deployment
### Production Deployment
For production, you can customize the docker-compose.yml:
```yaml
version: '3.8'
services:
zynktime:
image: zynktime:latest
restart: always
ports:
- "80:8000" # Expose on port 80
environment:
- KLEER_API_KEY=${KLEER_API_KEY}
- KLEER_USERNAME=${KLEER_USERNAME}
- KLEER_COMPANY_ID=${KLEER_COMPANY_ID}
env_file:
- .env
```
### Behind a Reverse Proxy
If deploying behind nginx or traefik:
```yaml
# docker-compose.yml
services:
zynktime:
image: zynktime:latest
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.zynktime.rule=Host(`time.example.com`)"
```
### Health Checks
The Docker container includes health checks:
- **Endpoint**: `/health`
- **Interval**: 30 seconds
- **Timeout**: 10 seconds
- **Retries**: 3
Monitor with:
```bash
docker-compose ps
docker inspect zynktime | grep Health
```
## License
This project is for internal use with the Kleer API.