docu: Add documentation for security, extensibility, deployment, and general overview
This commit is contained in:
parent
e31b93df93
commit
be6340332e
22
docu/README.md
Normal file
22
docu/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Time Tracking and Management System Documentation
|
||||
|
||||
# Time Tracking and Management System Documentation
|
||||
|
||||
This document provides an overview of the Time Tracking and Management System. For detailed information, please refer to the following documents:
|
||||
|
||||
- [General Overview](general_overview.md)
|
||||
- [Backend Architecture](backend_architecture.md)
|
||||
- [Frontend Architecture](frontend_architecture.md)
|
||||
- [Database Schema](database_schema.md)
|
||||
- [Deployment and DevOps](deployment_devops.md)
|
||||
- [Security and Privacy](security_privacy.md)
|
||||
- [Extensibility and Integrations](extensibility_integrations.md)
|
||||
- [LLM Guidance](llm_guidance.md)
|
||||
- [Roadmap](Roadmap.md)
|
||||
|
||||
## Code Examples
|
||||
- [GORM Entities](code_examples/gorm_entities.go)
|
||||
- [FPGO Repository](code_examples/fpgo_repository.go)
|
||||
- [FPGO Service](code_examples/fpgo_service.go)
|
||||
- [API Handler](code_examples/api_handler.go)
|
||||
- [React Component](code_examples/react_component.tsx)
|
153
docu/Roadmap.md
Normal file
153
docu/Roadmap.md
Normal file
@ -0,0 +1,153 @@
|
||||
# Time Tracking System Roadmap
|
||||
|
||||
This document outlines the roadmap for the development of the Time Tracking and Management System.
|
||||
|
||||
## Project Phases
|
||||
|
||||
### Phase 1: MVP (Minimum Viable Product)
|
||||
|
||||
**Goal:** A functional system with core time tracking capabilities, user authentication, and basic project/activity management.
|
||||
|
||||
**Sub-phases:**
|
||||
|
||||
1. **1.1 Core Backend Setup:**
|
||||
- Project initialization (Go, Next.js).
|
||||
- Database setup (PostgreSQL, GORM).
|
||||
- Basic API structure (Gin).
|
||||
- Authentication setup (JWT).
|
||||
|
||||
2. **1.2 User Management:**
|
||||
- User registration, login, and password management.
|
||||
- Implementation of basic user roles (User, Admin).
|
||||
|
||||
3. **1.3 Company Management:**
|
||||
- Company (tenant) creation and basic management (Admin only).
|
||||
|
||||
4. **1.4 Project and Activity Management:**
|
||||
- Project creation/editing/deletion (name, description, company association).
|
||||
- Activity creation/editing/deletion (name, billing rate, company association).
|
||||
|
||||
5. **1.5 Time Entry Core:**
|
||||
- Time entry creation (start/stop timer functionality).
|
||||
- Manual time entry input.
|
||||
|
||||
6. **1.6 Basic Frontend:**
|
||||
- Basic UI for time entry.
|
||||
- Basic UI for project/activity listing.
|
||||
|
||||
7. **1.7 Basic Listing and Filtering:**
|
||||
- Time entry listing.
|
||||
- Basic filtering (by user, project, date range).
|
||||
|
||||
8. **1.8 Simple Dashboard:**
|
||||
- Display of recent time entries.
|
||||
|
||||
### Phase 2: Version 1
|
||||
|
||||
**Goal:** Full implementation of the features described in the initial version of the specification.
|
||||
|
||||
**Sub-phases:**
|
||||
|
||||
1. **2.1 Expanded Roles:**
|
||||
- Implement Manager, Auditor, and Company roles.
|
||||
|
||||
2. **2.2 Client and Employee Management:**
|
||||
- Client creation/editing/deletion.
|
||||
- Employee creation/editing/deletion (with hourly rates).
|
||||
|
||||
3. **2.3 Detailed Time Entry:**
|
||||
- Add fields for location, purpose, description, and billable percentage to time entries.
|
||||
|
||||
4. **2.4 Reporting Engine:**
|
||||
- Implement report generation (by project, employee, client, time period).
|
||||
- PDF export for reports.
|
||||
|
||||
5. **2.5 Dashboard Enhancements:**
|
||||
- Add graphical dashboards with summaries and visualizations.
|
||||
|
||||
6. **2.6 Tracker Improvement:**
|
||||
- Pre-populate tracker with data from the last booking.
|
||||
|
||||
7. **2.7 Multi-Tenancy Refinement:**
|
||||
- Ensure complete data isolation between tenants.
|
||||
|
||||
8. **2.8 RBAC Implementation:**
|
||||
- Implement fine-grained Role-Based Access Control.
|
||||
|
||||
9. **2.9 API Documentation:**
|
||||
- Create comprehensive API documentation using Swagger.
|
||||
|
||||
10. **2.10 CI/CD Setup:**
|
||||
- Implement a basic CI/CD pipeline for automated testing and deployment.
|
||||
|
||||
### Phase 3: Version 2
|
||||
|
||||
**Goal:** Implement the "Future Enhancements" outlined in the specification.
|
||||
|
||||
**Sub-phases:**
|
||||
|
||||
1. **3.1 Sprint and Task Management:**
|
||||
- Add sprint and task entities to the data model.
|
||||
- Implement sprint and task creation/editing/deletion.
|
||||
|
||||
2. **3.2 Kanban Boards:**
|
||||
- Develop Kanban board UI components.
|
||||
- Implement drag-and-drop functionality for task management.
|
||||
|
||||
3. **3.3 Task-Time Entry Linking:**
|
||||
- Allow users to select a specific task when creating a time entry.
|
||||
|
||||
### Phase 4: Future Considerations
|
||||
|
||||
**Goal:** Expand the system with additional features and integrations.
|
||||
|
||||
**Sub-phases (Not exhaustive, can be further broken down):**
|
||||
|
||||
1. **4.1 Integrations:**
|
||||
- Billing systems integration.
|
||||
- Calendar integrations (Google Calendar, Outlook).
|
||||
- Project management tool integrations (Jira, Trello).
|
||||
- Webhook implementation.
|
||||
- SSO implementation.
|
||||
|
||||
2. **4.2 Extensibility:**
|
||||
- Develop a plugin system.
|
||||
- Implement custom fields.
|
||||
|
||||
3. **4.3 Mobile App:**
|
||||
- Develop responsive web design.
|
||||
- Explore native mobile app development.
|
||||
|
||||
4. **4.4 Internationalization:**
|
||||
- Implement multilingual support.
|
||||
- Add localized date/time formats.
|
||||
- Add currency conversion.
|
||||
|
||||
5. **4.5 Billing and Invoicing:**
|
||||
- Implement invoice generation.
|
||||
- Add billing data export functionality.
|
||||
- Implement reminders for unrecorded time.
|
||||
|
||||
6. **4.6 Notification System:**
|
||||
- Implement email and in-app notifications.
|
||||
- Add reminders and approval requests.
|
||||
|
||||
7. **4.7 Analytics:**
|
||||
- Implement advanced analytics and reporting.
|
||||
- Add trend analysis and forecasting.
|
||||
- Implement resource utilization tracking.
|
||||
- Add export options for BI tools.
|
||||
|
||||
8. **4.8 Offline Functionality**
|
||||
- Implement PWA features.
|
||||
- Add local storage and synchronization.
|
||||
|
||||
9. **4.9 Enhanced Security:**
|
||||
- Implement more detailed audit trails.
|
||||
|
||||
10. **4.10 Error Handling:**
|
||||
- Implement a unified error handling and validation strategy.
|
||||
|
||||
11. **4.11 Performance:**
|
||||
- Implement Caching (Redis).
|
||||
- Optimize database with indexing.
|
144
docu/backend_architecture.md
Normal file
144
docu/backend_architecture.md
Normal file
@ -0,0 +1,144 @@
|
||||
# Backend Architecture (Go)
|
||||
|
||||
**Note:** This document describes a *conceptual* architecture and is not a final, binding requirement.
|
||||
|
||||
The backend is written in Go and follows the principles of **Clean Architecture** and **Domain-Driven Design (DDD)**.
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
timetracker-backend/
|
||||
├── cmd/ # Einstiegspunkte
|
||||
│ ├── api/
|
||||
│ │ └── main.go
|
||||
│ └── worker/
|
||||
│ └── main.go
|
||||
├── internal/ # Interner Code
|
||||
│ ├── domain/ # Domain Layer (DDD)
|
||||
│ │ ├── entities/ # Domain Entitäten
|
||||
│ │ │ ├── user.go
|
||||
│ │ │ ├── company.go
|
||||
│ │ │ ├── project.go
|
||||
│ │ │ ├── timeentry.go
|
||||
│ │ │ ├── customer.go
|
||||
│ │ │ ├── activity.go
|
||||
│ │ │ ├── sprint.go
|
||||
│ │ │ ├── task.go
|
||||
│ │ │ └── kanban.go
|
||||
│ │ ├── repositories/ # Repository Interfaces
|
||||
│ │ │ ├── user_repository.go
|
||||
│ │ │ ├── company_repository.go
|
||||
│ │ │ ├── project_repository.go
|
||||
│ │ │ ├── timeentry_repository.go
|
||||
│ │ │ └── ...
|
||||
│ │ ├── services/ # Service Interfaces und Implementierungen
|
||||
│ │ │ ├── auth_service.go
|
||||
│ │ │ ├── user_service.go
|
||||
│ │ │ ├── timetracking_service.go
|
||||
│ │ │ ├── reporting_service.go
|
||||
│ │ │ └── ...
|
||||
│ │ └── valueobjects/ # Value Objects
|
||||
│ │ ├── money.go
|
||||
│ │ ├── duration.go
|
||||
│ │ └── ...
|
||||
│ ├── application/ # Anwendungsfälle
|
||||
│ │ ├── auth/ # Authentication Use Cases
|
||||
│ │ │ ├── login.go
|
||||
│ │ │ ├── register.go
|
||||
│ │ │ └── ...
|
||||
│ │ ├── timetracking/ # Zeiterfassung Use Cases
|
||||
│ │ │ ├── create_time_entry.go
|
||||
│ │ │ ├── update_time_entry.go
|
||||
│ │ │ ├── list_time_entries.go
|
||||
│ │ │ └── ...
|
||||
│ │ ├── projects/ # Projektverwaltung Use Cases
|
||||
│ │ │ └── ...
|
||||
│ │ ├── customers/ # Kundenverwaltung Use Cases
|
||||
│ │ │ └── ...
|
||||
│ │ └── reporting/ # Berichtswesen Use Cases
|
||||
│ │ └── ...
|
||||
│ ├── infrastructure/ # Infrastruktur
|
||||
│ │ ├── persistence/ # Datenbankzugriff
|
||||
│ │ │ ├── postgres/ # PostgreSQL Implementierung
|
||||
│ │ │ │ ├── connection.go
|
||||
│ │ │ │ ├── user_repository.go
|
||||
│ │ │ │ ├── company_repository.go
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ └── migrations/
|
||||
│ │ ├── security/ # Sicherheitsimplementierungen
|
||||
│ │ │ ├── jwt.go
|
||||
│ │ │ ├── password.go
|
||||
│ │ │ └── rbac.go
|
||||
│ │ ├── messaging/ # Messaging-Implementierungen
|
||||
│ │ │ ├── email.go
|
||||
│ │ │ └── notification.go
|
||||
│ │ └── external/ # Externe Dienste
|
||||
│ │ ├── calendar/
|
||||
│ │ ├── pdf/
|
||||
│ │ └── webhook/
|
||||
│ └── interfaces/ # Interfaces
|
||||
│ ├── http/ # HTTP-API
|
||||
│ │ ├── handlers/ # API Handler
|
||||
│ │ │ ├── auth_handler.go
|
||||
│ │ │ ├── user_handler.go
|
||||
│ │ │ ├── time_entry_handler.go
|
||||
│ │ │ └── ...
|
||||
│ │ ├── middleware/ # Middleware
|
||||
│ │ │ ├── auth_middleware.go
|
||||
│ │ │ ├── tenant_middleware.go
|
||||
│ │ │ ├── logging_middleware.go
|
||||
│ │ │ └── ...
|
||||
│ │ ├── dto/ # Data Transfer Objects
|
||||
│ │ │ ├── auth_dto.go
|
||||
│ │ │ ├── user_dto.go
|
||||
│ │ │ ├── time_entry_dto.go
|
||||
│ │ │ └── ...
|
||||
│ │ └── routes/ # API Routes
|
||||
│ │ └── router.go
|
||||
│ └── grpc/ # gRPC-API (Optional für Microservice-Kommunikation)
|
||||
├── pkg/ # Öffentliche Pakete
|
||||
│ ├── functional/ # FPGO Utilities
|
||||
│ │ ├── option.go
|
||||
│ │ ├── result.go
|
||||
│ │ └── ...
|
||||
│ ├── validator/ # Validierung
|
||||
│ │ └── validator.go
|
||||
│ ├── logger/ # Logging
|
||||
│ │ └── logger.go
|
||||
│ ├── errors/ # Fehlerbehandlung
|
||||
│ │ └── errors.go
|
||||
│ └── utils/ # Allgemeine Utilities
|
||||
│ ├── date.go
|
||||
│ ├── crypto.go
|
||||
│ └── ...
|
||||
├── api/ # API Definitionen
|
||||
│ └── swagger/ # Swagger Dokumentation
|
||||
│ └── swagger.yaml
|
||||
├── deployments/ # Deployment-Konfigurationen
|
||||
│ ├── docker/
|
||||
│ │ ├── Dockerfile
|
||||
│ │ └── docker-compose.yml
|
||||
│ └── kubernetes/
|
||||
│ ├── api.yaml
|
||||
│ └── worker.yaml
|
||||
├── test/ # Tests
|
||||
│ ├── unit/
|
||||
│ ├── integration/
|
||||
│ └── e2e/
|
||||
├── scripts/ # Skripte
|
||||
│ ├── migration.sh
|
||||
│ ├── seed.sh
|
||||
│ └── ...
|
||||
├── docu/ # Projektdokumentation
|
||||
│ ├── general_overview.md
|
||||
│ ├── backend_architecture.md
|
||||
│ ├── frontend_architecture.md
|
||||
│ ├── database_schema.md
|
||||
│ ├── security_privacy.md
|
||||
│ ├── extensibility_integrations.md
|
||||
│ ├── deployment_devops.md
|
||||
│ ├── llm_guidance.md
|
||||
│ └── README.md
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
└── README.md
|
||||
```
|
101
docu/code_examples/api_handler.go
Normal file
101
docu/code_examples/api_handler.go
Normal file
@ -0,0 +1,101 @@
|
||||
// interfaces/http/handlers/time_entry_handler.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/username/timetracker/internal/application/timetracking"
|
||||
"github.com/username/timetracker/internal/interfaces/http/dto"
|
||||
"github.com/username/timetracker/internal/interfaces/http/middleware"
|
||||
)
|
||||
|
||||
// TimeEntryHandler behandelt HTTP-Anfragen für Zeitbuchungen
|
||||
type TimeEntryHandler struct {
|
||||
createTimeEntryUseCase *timetracking.CreateTimeEntryUseCase
|
||||
updateTimeEntryUseCase *timetracking.UpdateTimeEntryUseCase
|
||||
listTimeEntriesUseCase *timetracking.ListTimeEntriesUseCase
|
||||
deleteTimeEntryUseCase *timetracking.DeleteTimeEntryUseCase
|
||||
}
|
||||
|
||||
// NewTimeEntryHandler erstellt einen neuen TimeEntryHandler
|
||||
func NewTimeEntryHandler(
|
||||
createTimeEntryUseCase *timetracking.CreateTimeEntryUseCase,
|
||||
updateTimeEntryUseCase *timetracking.UpdateTimeEntryUseCase,
|
||||
listTimeEntriesUseCase *timetracking.ListTimeEntriesUseCase,
|
||||
deleteTimeEntryUseCase *timetracking.DeleteTimeEntryUseCase,
|
||||
) *TimeEntryHandler {
|
||||
return &TimeEntryHandler{
|
||||
createTimeEntryUseCase: createTimeEntryUseCase,
|
||||
updateTimeEntryUseCase: updateTimeEntryUseCase,
|
||||
listTimeEntriesUseCase: listTimeEntriesUseCase,
|
||||
deleteTimeEntryUseCase: deleteTimeEntryUseCase,
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterRoutes registriert die Routen am Router
|
||||
func (h *TimeEntryHandler) RegisterRoutes(router *gin.RouterGroup) {
|
||||
timeEntries := router.Group("/time-entries")
|
||||
{
|
||||
timeEntries.GET("", h.ListTimeEntries)
|
||||
timeEntries.POST("", h.CreateTimeEntry)
|
||||
timeEntries.GET("/:id", h.GetTimeEntry)
|
||||
timeEntries.PUT("/:id", h.UpdateTimeEntry)
|
||||
timeEntries.DELETE("/:id", h.DeleteTimeEntry)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTimeEntry behandelt die Erstellung einer neuen Zeitbuchung
|
||||
func (h *TimeEntryHandler) CreateTimeEntry(c *gin.Context) {
|
||||
var req dto.CreateTimeEntryRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Tenant-ID aus dem Kontext extrahieren
|
||||
companyID, exists := middleware.GetCompanyID(c)
|
||||
if !exists {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Company ID not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Benutzer-ID aus dem Kontext oder Request
|
||||
var userID uuid.UUID
|
||||
if req.UserID != nil {
|
||||
userID = *req.UserID
|
||||
} else {
|
||||
currentUserID, exists := middleware.GetUserID(c)
|
||||
if !exists {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "User ID not found"})
|
||||
return
|
||||
}
|
||||
userID = currentUserID
|
||||
}
|
||||
|
||||
// Command erstellen
|
||||
cmd := timetracking.CreateTimeEntryCommand{
|
||||
UserID: userID,
|
||||
ProjectID: req.ProjectID,
|
||||
ActivityID: req.ActivityID,
|
||||
TaskID: req.TaskID,
|
||||
StartTime: req.StartTime,
|
||||
EndTime: req.EndTime,
|
||||
Description: req.Description,
|
||||
BillablePercentage: req.BillablePercentage,
|
||||
}
|
||||
|
||||
// UseCase ausführen
|
||||
result := h.createTimeEntryUseCase.Execute(c.Request.Context(), companyID, cmd)
|
||||
if result.IsFailure() {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error().Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// TimeEntry in Response-DTO umwandeln
|
||||
timeEntry := result.Value()
|
||||
response := dto.MapTimeEntryToDTO(*timeEntry)
|
||||
|
||||
c.JSON(http.StatusCreated, response)
|
||||
}
|
52
docu/code_examples/fpgo_repository.go
Normal file
52
docu/code_examples/fpgo_repository.go
Normal file
@ -0,0 +1,52 @@
|
||||
// domain/repositories/time_entry_repository.go
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/username/timetracker/internal/domain/entities"
|
||||
"github.com/username/timetracker/pkg/functional"
|
||||
)
|
||||
|
||||
// TimeEntryFilter enthält Filter für die Suche nach Zeitbuchungen
|
||||
type TimeEntryFilter struct {
|
||||
UserID *uuid.UUID
|
||||
ProjectID *uuid.UUID
|
||||
CustomerID *uuid.UUID
|
||||
StartDate *time.Time
|
||||
EndDate *time.Time
|
||||
ActivityID *uuid.UUID
|
||||
TaskID *uuid.UUID
|
||||
}
|
||||
|
||||
// TimeEntryRepository Interface für den Zugriff auf Zeitbuchungen
|
||||
type TimeEntryRepository interface {
|
||||
// FindByID sucht eine Zeitbuchung anhand ihrer ID
|
||||
FindByID(ctx context.Context, companyID, id uuid.UUID) functional.Result[*entities.TimeEntry]
|
||||
|
||||
// FindAll sucht alle Zeitbuchungen mit optionalen Filtern
|
||||
FindAll(ctx context.Context, companyID uuid.UUID, filter TimeEntryFilter) functional.Result[[]entities.TimeEntry]
|
||||
|
||||
// Create erstellt eine neue Zeitbuchung
|
||||
Create(ctx context.Context, entry *entities.TimeEntry) functional.Result[*entities.TimeEntry]
|
||||
|
||||
// Update aktualisiert eine bestehende Zeitbuchung
|
||||
Update(ctx context.Context, entry *entities.TimeEntry) functional.Result[*entities.TimeEntry]
|
||||
|
||||
// Delete löscht eine Zeitbuchung
|
||||
Delete(ctx context.Context, companyID, id uuid.UUID) functional.Result[bool]
|
||||
|
||||
// GetSummary berechnet eine Zusammenfassung der Zeitbuchungen
|
||||
GetSummary(ctx context.Context, companyID uuid.UUID, filter TimeEntryFilter) functional.Result[TimeEntrySummary]
|
||||
}
|
||||
|
||||
// TimeEntrySummary enthält zusammengefasste Informationen über Zeitbuchungen
|
||||
type TimeEntrySummary struct {
|
||||
TotalDuration int
|
||||
TotalBillableDuration int
|
||||
TotalAmount float64
|
||||
TotalBillableAmount float64
|
||||
EntriesCount int
|
||||
}
|
99
docu/code_examples/fpgo_service.go
Normal file
99
docu/code_examples/fpgo_service.go
Normal file
@ -0,0 +1,99 @@
|
||||
// application/timetracking/create_time_entry.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/username/timetracker/internal/domain/entities"
|
||||
"github.com/username/timetracker/internal/domain/repositories"
|
||||
"github.com/username/timetracker/pkg/functional"
|
||||
"github.com/username/timetracker/pkg/validator"
|
||||
)
|
||||
|
||||
// CreateTimeEntryCommand enthält die Daten zum Erstellen einer Zeitbuchung
|
||||
type CreateTimeEntryCommand struct {
|
||||
UserID uuid.UUID
|
||||
ProjectID uuid.UUID
|
||||
ActivityID uuid.UUID
|
||||
TaskID *uuid.UUID
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
Description string
|
||||
BillablePercentage int
|
||||
}
|
||||
|
||||
// CreateTimeEntryUseCase repräsentiert den Anwendungsfall zum Erstellen einer Zeitbuchung
|
||||
type CreateTimeEntryUseCase struct {
|
||||
timeEntryRepo repositories.TimeEntryRepository
|
||||
projectRepo repositories.ProjectRepository
|
||||
activityRepo repositories.ActivityRepository
|
||||
userRepo repositories.UserRepository
|
||||
}
|
||||
|
||||
// NewCreateTimeEntryUseCase erstellt eine neue Instanz des UseCase
|
||||
func NewCreateTimeEntryUseCase(
|
||||
timeEntryRepo repositories.TimeEntryRepository,
|
||||
projectRepo repositories.ProjectRepository,
|
||||
activityRepo repositories.ActivityRepository,
|
||||
userRepo repositories.UserRepository,
|
||||
) *CreateTimeEntryUseCase {
|
||||
return &CreateTimeEntryUseCase{
|
||||
timeEntryRepo: timeEntryRepo,
|
||||
projectRepo: projectRepo,
|
||||
activityRepo: activityRepo,
|
||||
userRepo: userRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute führt den Anwendungsfall aus
|
||||
func (uc *CreateTimeEntryUseCase) Execute(ctx context.Context, companyID uuid.UUID, cmd CreateTimeEntryCommand) functional.Result[*entities.TimeEntry] {
|
||||
// Validierung
|
||||
if err := validator.ValidateStruct(cmd); err != nil {
|
||||
return functional.Failure[*entities.TimeEntry](err)
|
||||
}
|
||||
|
||||
// Überprüfen, ob Projekt existiert und zum gleichen Tenant gehört
|
||||
projectResult := uc.projectRepo.FindByID(ctx, companyID, cmd.ProjectID)
|
||||
if projectResult.IsFailure() {
|
||||
return functional.Failure[*entities.TimeEntry](projectResult.Error())
|
||||
}
|
||||
|
||||
// Überprüfen, ob Activity existiert und zum gleichen Tenant gehört
|
||||
activityResult := uc.activityRepo.FindByID(ctx, companyID, cmd.ActivityID)
|
||||
if activityResult.IsFailure() {
|
||||
return functional.Failure[*entities.TimeEntry](activityResult.Error())
|
||||
}
|
||||
activity := activityResult.Value()
|
||||
|
||||
// Benutzer abrufen für den Stundensatz
|
||||
userResult := uc.userRepo.FindByID(ctx, companyID, cmd.UserID)
|
||||
if userResult.IsFailure() {
|
||||
return functional.Failure[*entities.TimeEntry](userResult.Error())
|
||||
}
|
||||
user := userResult.Value()
|
||||
|
||||
// Berechnung der Dauer in Minuten
|
||||
durationMinutes := int(cmd.EndTime.Sub(cmd.StartTime).Minutes())
|
||||
|
||||
// TimeEntry erstellen
|
||||
timeEntry := &entities.TimeEntry{
|
||||
TenantEntity: entities.TenantEntity{
|
||||
CompanyID: companyID,
|
||||
},
|
||||
UserID: cmd.UserID,
|
||||
ProjectID: cmd.ProjectID,
|
||||
ActivityID: cmd.ActivityID,
|
||||
TaskID: cmd.TaskID,
|
||||
StartTime: cmd.StartTime,
|
||||
EndTime: cmd.EndTime,
|
||||
DurationMinutes: durationMinutes,
|
||||
Description: cmd.Description,
|
||||
BillablePercentage: cmd.BillablePercentage,
|
||||
BillingRate: activity.BillingRate,
|
||||
}
|
||||
|
||||
// Speichern der TimeEntry
|
||||
return uc.timeEntryRepo.Create(ctx, timeEntry)
|
||||
}
|
104
docu/code_examples/gorm_entities.go
Normal file
104
docu/code_examples/gorm_entities.go
Normal file
@ -0,0 +1,104 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// BaseEntity enthält gemeinsame Felder für alle Entitäten
|
||||
type BaseEntity struct {
|
||||
ID uuid.UUID `gorm:"type:uuid;primary_key"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
}
|
||||
|
||||
// BeforeCreate setzt eine neue UUID vor dem Erstellen
|
||||
func (base *BaseEntity) BeforeCreate(tx *gorm.DB) error {
|
||||
if base.ID == uuid.Nil {
|
||||
base.ID = uuid.New()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TenantEntity erweitert BaseEntity um Company-ID für Multi-Tenancy
|
||||
type TenantEntity struct {
|
||||
BaseEntity
|
||||
CompanyID uuid.UUID `gorm:"type:uuid;index:idx_tenant"`
|
||||
}
|
||||
|
||||
// Role repräsentiert eine Benutzerrolle
|
||||
type Role struct {
|
||||
BaseEntity
|
||||
Name string `gorm:"unique;not null"`
|
||||
Description string
|
||||
Permissions []Permission `gorm:"many2many:role_permissions;"`
|
||||
}
|
||||
|
||||
// Permission repräsentiert eine einzelne Berechtigung
|
||||
type Permission struct {
|
||||
BaseEntity
|
||||
Resource string `gorm:"not null"`
|
||||
Action string `gorm:"not null"`
|
||||
UniqueID string `gorm:"uniqueIndex"`
|
||||
}
|
||||
|
||||
// User repräsentiert einen Benutzer im System
|
||||
type User struct {
|
||||
TenantEntity
|
||||
Email string `gorm:"uniqueIndex;not null"`
|
||||
FirstName string
|
||||
LastName string
|
||||
PasswordHash string `gorm:"not null"`
|
||||
RoleID uuid.UUID `gorm:"type:uuid"`
|
||||
Role Role `gorm:"foreignKey:RoleID"`
|
||||
HourlyRate float64
|
||||
IsActive bool `gorm:"default:true"`
|
||||
}
|
||||
|
||||
// FullName gibt den vollständigen Namen des Benutzers zurück
|
||||
func (u User) FullName() string {
|
||||
return u.FirstName + " " + u.LastName
|
||||
}
|
||||
|
||||
// TimeEntry repräsentiert eine Zeitbuchung
|
||||
type TimeEntry struct {
|
||||
TenantEntity
|
||||
UserID uuid.UUID `gorm:"type:uuid;index:idx_user"`
|
||||
User User `gorm:"foreignKey:UserID"`
|
||||
ProjectID uuid.UUID `gorm:"type:uuid;index:idx_project"`
|
||||
Project Project `gorm:"foreignKey:ProjectID"`
|
||||
ActivityID uuid.UUID `gorm:"type:uuid"`
|
||||
Activity Activity `gorm:"foreignKey:ActivityID"`
|
||||
TaskID *uuid.UUID `gorm:"type:uuid;null"`
|
||||
Task *Task `gorm:"foreignKey:TaskID"`
|
||||
StartTime time.Time `gorm:"not null;index:idx_time_range"`
|
||||
EndTime time.Time `gorm:"not null;index:idx_time_range"`
|
||||
DurationMinutes int `gorm:"not null"`
|
||||
Description string
|
||||
BillablePercentage int `gorm:"default:100"`
|
||||
BillingRate float64
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
TenantEntity
|
||||
Name string
|
||||
}
|
||||
|
||||
type Activity struct {
|
||||
TenantEntity
|
||||
Name string
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
TenantEntity
|
||||
Name string
|
||||
}
|
||||
|
||||
// CalculateBillableAmount berechnet den abrechenbaren Betrag
|
||||
func (t TimeEntry) CalculateBillableAmount() float64 {
|
||||
hours := float64(t.DurationMinutes) / 60.0
|
||||
return hours * t.BillingRate * (float64(t.BillablePercentage) / 100.0)
|
||||
}
|
136
docu/code_examples/react_component.tsx
Normal file
136
docu/code_examples/react_component.tsx
Normal file
@ -0,0 +1,136 @@
|
||||
// presentation/components/timeTracker/Timer/Timer.tsx
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useTimeTracking } from '../../../hooks/useTimeTracking';
|
||||
import { pipe, Option, fromNullable } from '../../../../utils/fp/option';
|
||||
import { Button } from '../../common/Button';
|
||||
import { formatDuration } from '../../../../utils/date/dateUtils';
|
||||
|
||||
interface TimerProps {
|
||||
onComplete?: (duration: number) => void;
|
||||
}
|
||||
|
||||
export const Timer: React.FC<TimerProps> = ({ onComplete }) => {
|
||||
const [isRunning, setIsRunning] = useState(false);
|
||||
const [startTime, setStartTime] = useState<Option<Date>>(Option.none());
|
||||
const [elapsedTime, setElapsedTime] = useState(0);
|
||||
const [selectedProject, setSelectedProject] = useState<Option<string>>(Option.none());
|
||||
const [selectedActivity, setSelectedActivity] = useState<Option<string>>(Option.none());
|
||||
|
||||
const { lastTimeEntry, projects, activities } = useTimeTracking();
|
||||
|
||||
// Beim ersten Rendering die letzte Zeitbuchung laden
|
||||
useEffect(() => {
|
||||
pipe(
|
||||
fromNullable(lastTimeEntry),
|
||||
Option.map(entry => {
|
||||
setSelectedProject(Option.some(entry.projectId));
|
||||
setSelectedActivity(Option.some(entry.activityId));
|
||||
})
|
||||
);
|
||||
}, [lastTimeEntry]);
|
||||
|
||||
// Timer-Logik
|
||||
useEffect(() => {
|
||||
let interval: NodeJS.Timeout | null = null;
|
||||
|
||||
if (isRunning) {
|
||||
interval = setInterval(() => {
|
||||
const now = new Date();
|
||||
pipe(
|
||||
startTime,
|
||||
Option.map(start => {
|
||||
const diff = now.getTime() - start.getTime();
|
||||
setElapsedTime(Math.floor(diff / 1000));
|
||||
})
|
||||
);
|
||||
}, 1000);
|
||||
} else if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (interval) clearInterval(interval);
|
||||
};
|
||||
}, [isRunning, startTime]);
|
||||
|
||||
// Timer starten
|
||||
const handleStart = () => {
|
||||
setStartTime(Option.some(new Date()));
|
||||
setIsRunning(true);
|
||||
};
|
||||
|
||||
// Timer stoppen
|
||||
const handleStop = () => {
|
||||
setIsRunning(false);
|
||||
|
||||
// Prüfen, ob Projekt und Aktivität ausgewählt wurden
|
||||
const projectId = pipe(
|
||||
selectedProject,
|
||||
Option.getOrElse(() => '')
|
||||
);
|
||||
|
||||
const activityId = pipe(
|
||||
selectedActivity,
|
||||
Option.getOrElse(() => '')
|
||||
);
|
||||
|
||||
if (projectId && activityId && onComplete) {
|
||||
onComplete(elapsedTime);
|
||||
}
|
||||
|
||||
// Timer zurücksetzen
|
||||
setElapsedTime(0);
|
||||
setStartTime(Option.none());
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow-md p-4">
|
||||
<div className="text-4xl text-center font-mono mb-4">
|
||||
{formatDuration(elapsedTime)}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 mb-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Projekt
|
||||
</label>
|
||||
<select
|
||||
className="w-full border border-gray-300 rounded-md px-3 py-2"
|
||||
value={pipe(selectedProject, Option.getOrElse(() => ''))}
|
||||
onChange={(e) => setSelectedProject(Option.some(e.target.value))}
|
||||
disabled={isRunning}
|
||||
>
|
||||
<option value="">Projekt auswählen</option>
|
||||
{projects.map((project) => (
|
||||
<option key={project.id} value={project.id}>
|
||||
{project.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Tätigkeit
|
||||
</label>
|
||||
<select
|
||||
className="w-full border border-gray-300 rounded-md px-3 py-2"
|
||||
value={pipe(selectedActivity, Option.getOrElse(() => ''))}
|
||||
onChange={(e) => setSelectedActivity(Option.some(e.target.value))}
|
||||
disabled={isRunning}
|
||||
>
|
||||
<option value="">Tätigkeit auswählen</option>
|
||||
{activities.map((activity) => (
|
||||
<option key={activity.id} value={activity.id}>
|
||||
{activity.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,103 +0,0 @@
|
||||
timetracker-frontend/
|
||||
├── public/ # Statische Dateien
|
||||
│ ├── assets/
|
||||
│ │ ├── images/
|
||||
│ │ ├── icons/
|
||||
│ │ └── fonts/
|
||||
│ └── locales/ # Mehrsprachige Inhalte
|
||||
│ ├── de/
|
||||
│ └── en/
|
||||
├── src/
|
||||
│ ├── app/ # Next.js 13+ App Router
|
||||
│ │ ├── api/ # API-Routen (falls nötig)
|
||||
│ │ ├── (auth)/ # Authentifizierungsseiten
|
||||
│ │ │ ├── login/
|
||||
│ │ │ └── register/
|
||||
│ │ ├── dashboard/ # Dashboard-Seiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── layout.tsx
|
||||
│ │ ├── time-tracking/ # Zeiterfassungsseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ ├── [id]/
|
||||
│ │ │ └── components/
|
||||
│ │ ├── projects/ # Projektseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [id]/
|
||||
│ │ ├── customers/ # Kundenseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [id]/
|
||||
│ │ ├── reports/ # Berichtsseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [type]/
|
||||
│ │ ├── admin/ # Administrationsseiten
|
||||
│ │ │ ├── users/
|
||||
│ │ │ ├── companies/
|
||||
│ │ │ └── settings/
|
||||
│ │ ├── kanban/ # Kanban-Boards (Version 2)
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [id]/
|
||||
│ │ ├── layout.tsx
|
||||
│ │ └── page.tsx
|
||||
│ ├── components/ # Wiederverwendbare Komponenten
|
||||
│ │ ├── common/ # Allgemeine Komponenten
|
||||
│ │ │ ├── Button.tsx
|
||||
│ │ │ ├── Card.tsx
|
||||
│ │ │ ├── Input.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── layout/ # Layout-Komponenten
|
||||
│ │ │ ├── Navbar.tsx
|
||||
│ │ │ ├── Sidebar.tsx
|
||||
│ │ │ ├── Footer.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── dashboard/ # Dashboard-Komponenten
|
||||
│ │ │ ├── ActivityChart.tsx
|
||||
│ │ │ ├── RecentEntries.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── timetracker/ # Zeiterfassungskomponenten
|
||||
│ │ │ ├── Timer.tsx
|
||||
│ │ │ ├── EntryForm.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── reports/ # Berichtskomponenten
|
||||
│ │ │ ├── ReportFilter.tsx
|
||||
│ │ │ ├── Chart.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ └── kanban/ # Kanban-Komponenten (Version 2)
|
||||
│ │ ├── Board.tsx
|
||||
│ │ ├── Column.tsx
|
||||
│ │ ├── Card.tsx
|
||||
│ │ └── ...
|
||||
│ ├── hooks/ # Custom React Hooks
|
||||
│ │ ├── useAuth.ts
|
||||
│ │ ├── useTimeTracking.ts
|
||||
│ │ ├── useProjects.ts
|
||||
│ │ └── ...
|
||||
│ ├── lib/ # Hilfsfunktionen und Bibliotheken
|
||||
│ │ ├── api.ts # API Client
|
||||
│ │ ├── auth.ts # Auth-Utilities
|
||||
│ │ ├── date-utils.ts # Date-Helpers
|
||||
│ │ └── ...
|
||||
│ ├── types/ # TypeScript-Typdefinitionen
|
||||
│ │ ├── auth.ts
|
||||
│ │ ├── user.ts
|
||||
│ │ ├── timeTracking.ts
|
||||
│ │ ├── project.ts
|
||||
│ │ └── ...
|
||||
│ ├── store/ # State Management (falls benötigt)
|
||||
│ │ ├── slices/
|
||||
│ │ └── index.ts
|
||||
│ ├── styles/ # CSS/SCSS Styles
|
||||
│ │ ├── globals.css
|
||||
│ │ └── theme.ts
|
||||
│ └── utils/ # Allgemeine Hilfsfunktionen
|
||||
│ ├── format.ts
|
||||
│ ├── validation.ts
|
||||
│ └── ...
|
||||
├── .env.local.example
|
||||
├── .eslintrc.json
|
||||
├── next.config.js
|
||||
├── package.json
|
||||
├── tailwind.config.js
|
||||
├── tsconfig.json
|
||||
├── jest.config.js # Test-Konfiguration
|
||||
├── postcss.config.js # PostCSS-Konfiguration
|
||||
└── README.md
|
160
docu/database_schema.md
Normal file
160
docu/database_schema.md
Normal file
@ -0,0 +1,160 @@
|
||||
# Database Schema (PostgreSQL)
|
||||
|
||||
```sql
|
||||
-- Multi-Tenant
|
||||
CREATE TABLE companies (
|
||||
id UUID PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
address TEXT,
|
||||
contact_email VARCHAR(255),
|
||||
contact_phone VARCHAR(50),
|
||||
logo_url TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Users and Roles
|
||||
CREATE TABLE roles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(50) UNIQUE NOT NULL,
|
||||
permissions JSONB
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID REFERENCES companies(id),
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
first_name VARCHAR(100),
|
||||
last_name VARCHAR(100),
|
||||
role_id INTEGER REFERENCES roles(id),
|
||||
hourly_rate DECIMAL(10, 2),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Customers
|
||||
CREATE TABLE customers (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
contact_person VARCHAR(255),
|
||||
email VARCHAR(255),
|
||||
phone VARCHAR(50),
|
||||
address TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Projects
|
||||
CREATE TABLE projects (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
customer_id UUID REFERENCES customers(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
status VARCHAR(50),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Activities
|
||||
CREATE TABLE activities (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
billing_rate DECIMAL(10, 2),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Time bookings
|
||||
CREATE TABLE time_entries (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
activity_id UUID NOT NULL REFERENCES activities(id),
|
||||
start_time TIMESTAMP NOT NULL,
|
||||
end_time TIMESTAMP NOT NULL,
|
||||
duration INTEGER NOT NULL, -- in minutes
|
||||
description TEXT,
|
||||
billable_percentage INTEGER NOT NULL DEFAULT 100,
|
||||
billing_rate DECIMAL(10, 2),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Version 2: Sprint/Task Management
|
||||
CREATE TABLE sprints (
|
||||
id UUID PRIMARY KEY,
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE NOT NULL,
|
||||
status VARCHAR(50),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE task_statuses (
|
||||
id SERIAL PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
color VARCHAR(7),
|
||||
position INTEGER NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
sprint_id UUID REFERENCES sprints(id),
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
assignee_id UUID REFERENCES users(id),
|
||||
status_id INTEGER REFERENCES task_statuses(id),
|
||||
priority VARCHAR(50),
|
||||
estimate INTEGER, -- in minutes
|
||||
due_date TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE kanban_boards (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE kanban_columns (
|
||||
id UUID PRIMARY KEY,
|
||||
board_id UUID NOT NULL REFERENCES kanban_boards(id),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
position INTEGER NOT NULL,
|
||||
task_status_id INTEGER REFERENCES task_statuses(id),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Linking time entries and tasks
|
||||
ALTER TABLE time_entries ADD COLUMN task_id UUID REFERENCES tasks(id);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX idx_time_entries_user ON time_entries(user_id);
|
||||
CREATE INDEX idx_time_entries_project ON time_entries(project_id);
|
||||
CREATE INDEX idx_time_entries_date ON time_entries(start_time);
|
||||
CREATE INDEX idx_projects_company ON projects(company_id);
|
||||
CREATE INDEX idx_users_company ON users(company_id);
|
||||
CREATE INDEX idx_tasks_project ON tasks(project_id);
|
||||
CREATE INDEX idx_tasks_sprint ON tasks(sprint_id);
|
17
docu/deployment_devops.md
Normal file
17
docu/deployment_devops.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Deployment and DevOps
|
||||
|
||||
## Containerization
|
||||
- Docker containers for backend and frontend
|
||||
- Docker Compose for development environment
|
||||
- Kubernetes manifests for production environment
|
||||
|
||||
## CI/CD Pipeline
|
||||
- Automated tests (Unit, Integration, E2E)
|
||||
- Automated deployment
|
||||
- Version management
|
||||
|
||||
## Monitoring and Logging
|
||||
- Prometheus for metrics
|
||||
- Grafana for visualization
|
||||
- ELK Stack or similar for logging
|
||||
- Alerting for critical events
|
389
docu/draft/concept/claude.md
Normal file
389
docu/draft/concept/claude.md
Normal file
@ -0,0 +1,389 @@
|
||||
# Zeiterfassungstool - Projektstruktur
|
||||
|
||||
## Backend (Go)
|
||||
|
||||
```
|
||||
timetracker-backend/
|
||||
├── cmd/ # Einstiegspunkte für die Anwendung
|
||||
│ ├── api/ # API-Server
|
||||
│ │ └── main.go
|
||||
│ └── worker/ # Hintergrundprozesse (Reports, Benachrichtigungen usw.)
|
||||
│ └── main.go
|
||||
├── internal/ # Interner Code, nicht exportierbar
|
||||
│ ├── auth/ # Authentifizierung und Autorisierung
|
||||
│ │ ├── jwt.go
|
||||
│ │ ├── middleware.go
|
||||
│ │ ├── permissions.go
|
||||
│ │ └── service.go
|
||||
│ ├── tenant/ # Multi-Tenant-Funktionalität
|
||||
│ │ ├── middleware.go
|
||||
│ │ └── service.go
|
||||
│ ├── user/ # Benutzerverwaltung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── company/ # Unternehmensverwaltung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── customer/ # Kundenverwaltung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── project/ # Projektverwaltung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── activity/ # Tätigkeitsverwaltung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── timetracking/ # Zeiterfassung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── billing/ # Abrechnung
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── reporting/ # Berichtswesen
|
||||
│ │ ├── generator.go
|
||||
│ │ ├── pdf.go
|
||||
│ │ └── service.go
|
||||
│ ├── notification/ # Benachrichtigungen
|
||||
│ │ ├── email.go
|
||||
│ │ ├── inapp.go
|
||||
│ │ └── service.go
|
||||
│ ├── kanban/ # Kanban-Board (Version 2)
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── task/ # Task-Management (Version 2)
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── sprint/ # Sprint-Management (Version 2)
|
||||
│ │ ├── model.go
|
||||
│ │ ├── repository.go
|
||||
│ │ └── service.go
|
||||
│ ├── config/ # Konfiguration
|
||||
│ │ └── config.go
|
||||
│ └── database/ # Datenbankzugriff
|
||||
│ ├── migrations/
|
||||
│ ├── seeds/
|
||||
│ └── connection.go
|
||||
├── pkg/ # Öffentliche Pakete, die exportiert werden können
|
||||
│ ├── apierror/ # API-Fehlerobjekte
|
||||
│ │ └── error.go
|
||||
│ ├── logger/ # Logging-Funktionalität
|
||||
│ │ └── logger.go
|
||||
│ ├── validator/ # Validierungsfunktionen
|
||||
│ │ └── validator.go
|
||||
│ └── utils/ # Allgemeine Hilfsfunktionen
|
||||
│ ├── dates.go
|
||||
│ ├── encryption.go
|
||||
│ └── helpers.go
|
||||
├── api/ # API-Definitionen
|
||||
│ ├── handlers/ # API-Handler
|
||||
│ │ ├── auth.go
|
||||
│ │ ├── user.go
|
||||
│ │ ├── company.go
|
||||
│ │ ├── customer.go
|
||||
│ │ ├── project.go
|
||||
│ │ ├── timetracking.go
|
||||
│ │ ├── reporting.go
|
||||
│ │ └── task.go
|
||||
│ ├── middleware/ # API-Middleware
|
||||
│ │ ├── auth.go
|
||||
│ │ ├── tenant.go
|
||||
│ │ └── logging.go
|
||||
│ ├── routes/ # API-Routen
|
||||
│ │ └── routes.go
|
||||
│ └── swagger/ # Swagger-Dokumentation
|
||||
│ └── swagger.yaml
|
||||
├── test/ # Tests
|
||||
│ ├── integration/
|
||||
│ ├── unit/
|
||||
│ └── mocks/
|
||||
├── scripts/ # Skripte für Build, Deployment usw.
|
||||
│ ├── build.sh
|
||||
│ ├── migrate.sh
|
||||
│ └── seed.sh
|
||||
├── docker/ # Docker-Konfiguration
|
||||
│ ├── Dockerfile
|
||||
│ └── docker-compose.yml
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── .env.example
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Frontend (NextJS)
|
||||
|
||||
```
|
||||
timetracker-frontend/
|
||||
├── public/ # Statische Dateien
|
||||
│ ├── assets/
|
||||
│ │ ├── images/
|
||||
│ │ ├── icons/
|
||||
│ │ └── fonts/
|
||||
│ └── locales/ # Mehrsprachige Inhalte
|
||||
│ ├── de/
|
||||
│ └── en/
|
||||
├── src/
|
||||
│ ├── app/ # Next.js 13+ App Router
|
||||
│ │ ├── api/ # API-Routen (falls nötig)
|
||||
│ │ ├── (auth)/ # Authentifizierungsseiten
|
||||
│ │ │ ├── login/
|
||||
│ │ │ └── register/
|
||||
│ │ ├── dashboard/ # Dashboard-Seiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── layout.tsx
|
||||
│ │ ├── time-tracking/ # Zeiterfassungsseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ ├── [id]/
|
||||
│ │ │ └── components/
|
||||
│ │ ├── projects/ # Projektseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [id]/
|
||||
│ │ ├── customers/ # Kundenseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [id]/
|
||||
│ │ ├── reports/ # Berichtsseiten
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [type]/
|
||||
│ │ ├── admin/ # Administrationsseiten
|
||||
│ │ │ ├── users/
|
||||
│ │ │ ├── companies/
|
||||
│ │ │ └── settings/
|
||||
│ │ ├── kanban/ # Kanban-Boards (Version 2)
|
||||
│ │ │ ├── page.tsx
|
||||
│ │ │ └── [id]/
|
||||
│ │ ├── layout.tsx
|
||||
│ │ └── page.tsx
|
||||
│ ├── components/ # Wiederverwendbare Komponenten
|
||||
│ │ ├── common/ # Allgemeine Komponenten
|
||||
│ │ │ ├── Button.tsx
|
||||
│ │ │ ├── Card.tsx
|
||||
│ │ │ ├── Input.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── layout/ # Layout-Komponenten
|
||||
│ │ │ ├── Navbar.tsx
|
||||
│ │ │ ├── Sidebar.tsx
|
||||
│ │ │ ├── Footer.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── dashboard/ # Dashboard-Komponenten
|
||||
│ │ │ ├── ActivityChart.tsx
|
||||
│ │ │ ├── RecentEntries.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── timetracker/ # Zeiterfassungskomponenten
|
||||
│ │ │ ├── Timer.tsx
|
||||
│ │ │ ├── EntryForm.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ ├── reports/ # Berichtskomponenten
|
||||
│ │ │ ├── ReportFilter.tsx
|
||||
│ │ │ ├── Chart.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ └── kanban/ # Kanban-Komponenten (Version 2)
|
||||
│ │ ├── Board.tsx
|
||||
│ │ ├── Column.tsx
|
||||
│ │ ├── Card.tsx
|
||||
│ │ └── ...
|
||||
│ ├── hooks/ # Custom React Hooks
|
||||
│ │ ├── useAuth.ts
|
||||
│ │ ├── useTimeTracking.ts
|
||||
│ │ ├── useProjects.ts
|
||||
│ │ └── ...
|
||||
│ ├── lib/ # Hilfsfunktionen und Bibliotheken
|
||||
│ │ ├── api.ts # API Client
|
||||
│ │ ├── auth.ts # Auth-Utilities
|
||||
│ │ ├── date-utils.ts # Date-Helpers
|
||||
│ │ └── ...
|
||||
│ ├── types/ # TypeScript-Typdefinitionen
|
||||
│ │ ├── auth.ts
|
||||
│ │ ├── user.ts
|
||||
│ │ ├── timeTracking.ts
|
||||
│ │ ├── project.ts
|
||||
│ │ └── ...
|
||||
│ ├── store/ # State Management (falls benötigt)
|
||||
│ │ ├── slices/
|
||||
│ │ └── index.ts
|
||||
│ ├── styles/ # CSS/SCSS Styles
|
||||
│ │ ├── globals.css
|
||||
│ │ └── theme.ts
|
||||
│ └── utils/ # Allgemeine Hilfsfunktionen
|
||||
│ ├── format.ts
|
||||
│ ├── validation.ts
|
||||
│ └── ...
|
||||
├── .env.local.example
|
||||
├── .eslintrc.json
|
||||
├── next.config.js
|
||||
├── package.json
|
||||
├── tailwind.config.js
|
||||
├── tsconfig.json
|
||||
├── jest.config.js # Test-Konfiguration
|
||||
├── postcss.config.js # PostCSS-Konfiguration
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Datenbankschema (PostgreSQL)
|
||||
|
||||
```sql
|
||||
-- Multi-Tenant
|
||||
CREATE TABLE companies (
|
||||
id UUID PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
address TEXT,
|
||||
contact_email VARCHAR(255),
|
||||
contact_phone VARCHAR(50),
|
||||
logo_url TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Benutzer und Rollen
|
||||
CREATE TABLE roles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(50) UNIQUE NOT NULL,
|
||||
permissions JSONB
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID REFERENCES companies(id),
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
first_name VARCHAR(100),
|
||||
last_name VARCHAR(100),
|
||||
role_id INTEGER REFERENCES roles(id),
|
||||
hourly_rate DECIMAL(10, 2),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Kunden
|
||||
CREATE TABLE customers (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
contact_person VARCHAR(255),
|
||||
email VARCHAR(255),
|
||||
phone VARCHAR(50),
|
||||
address TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Projekte
|
||||
CREATE TABLE projects (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
customer_id UUID REFERENCES customers(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
status VARCHAR(50),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Tätigkeiten
|
||||
CREATE TABLE activities (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
billing_rate DECIMAL(10, 2),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Zeitbuchungen
|
||||
CREATE TABLE time_entries (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
user_id UUID NOT NULL REFERENCES users(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
activity_id UUID NOT NULL REFERENCES activities(id),
|
||||
start_time TIMESTAMP NOT NULL,
|
||||
end_time TIMESTAMP NOT NULL,
|
||||
duration INTEGER NOT NULL, -- in minutes
|
||||
description TEXT,
|
||||
billable_percentage INTEGER NOT NULL DEFAULT 100,
|
||||
billing_rate DECIMAL(10, 2),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Version 2: Sprint/Task Management
|
||||
CREATE TABLE sprints (
|
||||
id UUID PRIMARY KEY,
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE NOT NULL,
|
||||
status VARCHAR(50),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE task_statuses (
|
||||
id SERIAL PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
color VARCHAR(7),
|
||||
position INTEGER NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
sprint_id UUID REFERENCES sprints(id),
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
assignee_id UUID REFERENCES users(id),
|
||||
status_id INTEGER REFERENCES task_statuses(id),
|
||||
priority VARCHAR(50),
|
||||
estimate INTEGER, -- in minutes
|
||||
due_date TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE kanban_boards (
|
||||
id UUID PRIMARY KEY,
|
||||
company_id UUID NOT NULL REFERENCES companies(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE kanban_columns (
|
||||
id UUID PRIMARY KEY,
|
||||
board_id UUID NOT NULL REFERENCES kanban_boards(id),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
position INTEGER NOT NULL,
|
||||
task_status_id INTEGER REFERENCES task_statuses(id),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Verknüpfung zwischen Zeitbuchungen und Tasks
|
||||
ALTER TABLE time_entries ADD COLUMN task_id UUID REFERENCES tasks(id);
|
||||
|
||||
-- Indizes für Performance
|
||||
CREATE INDEX idx_time_entries_user ON time_entries(user_id);
|
||||
CREATE INDEX idx_time_entries_project ON time_entries(project_id);
|
||||
CREATE INDEX idx_time_entries_date ON time_entries(start_time);
|
||||
CREATE INDEX idx_projects_company ON projects(company_id);
|
||||
CREATE INDEX idx_users_company ON users(company_id);
|
||||
CREATE INDEX idx_tasks_project ON tasks(project_id);
|
||||
CREATE INDEX idx_tasks_sprint ON tasks(sprint_id);
|
||||
```
|
6
docu/extensibility_integrations.md
Normal file
6
docu/extensibility_integrations.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Extensibility and Integrations
|
||||
|
||||
- API for external billing systems and calendar integration
|
||||
- Single Sign-On (Google, Microsoft, SAML)
|
||||
- Plugin system and custom fields for extensibility
|
||||
- Analytics and BI export
|
102
docu/frontend_architecture.md
Normal file
102
docu/frontend_architecture.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Frontend Architecture (Next.js)
|
||||
|
||||
**Note:** This document describes a *conceptual* architecture and is not a final, binding requirement.
|
||||
|
||||
The frontend uses **Next.js** with **TypeScript** and **FPTS** for functional programming.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
timetracker-frontend/
|
||||
├── public/ # Statische Dateien
|
||||
│ ├── assets/
|
||||
│ └── locales/ # i18n Übersetzungen
|
||||
├── src/
|
||||
│ ├── app/ # Next.js App Router
|
||||
│ │ ├── api/ # API Routes
|
||||
│ │ ├── (auth)/ # Auth Pages
|
||||
│ │ ├── dashboard/
|
||||
│ │ ├── time-tracking/
|
||||
│ │ ├── projects/
|
||||
│ │ └── ...
|
||||
│ ├── domain/ # Domain Model (analog zu Backend)
|
||||
│ │ ├── entities/ # Domain Entities
|
||||
│ │ │ ├── user.ts
|
||||
│ │ │ ├── timeEntry.ts
|
||||
│ │ │ ├── project.ts
|
||||
│ │ │ └── ...
|
||||
│ │ └── valueObjects/ # Value Objects
|
||||
│ │ ├── money.ts
|
||||
│ │ ├── duration.ts
|
||||
│ │ └── ...
|
||||
│ ├── application/ # Anwendungsfälle
|
||||
│ │ ├── auth/ # Auth Use Cases
|
||||
│ │ ├── timeTracking/ # Time Tracking Use Cases
|
||||
│ │ ├── projects/ # Projects Use Cases
|
||||
│ │ └── ...
|
||||
│ ├── infrastructure/ # Infrastruktur
|
||||
│ │ ├── api/ # API Client
|
||||
│ │ │ ├── apiClient.ts # Axios Konfiguration
|
||||
│ │ │ ├── endpoints.ts # API Endpunkte
|
||||
│ │ │ └── interceptors.ts # Request/Response Interceptors
|
||||
│ │ ├── storage/ # Lokale Speicherung
|
||||
│ │ │ ├── localStorage.ts
|
||||
│ │ │ └── sessionStorage.ts
|
||||
│ │ └── external/ # Externe Dienste
|
||||
│ │ └── ...
|
||||
│ ├── presentation/ # Präsentationsschicht
|
||||
│ │ ├── components/ # UI Komponenten
|
||||
│ │ │ ├── common/ # Allgemeine Komponenten
|
||||
│ │ │ │ ├── Button/
|
||||
│ │ │ │ ├── Card/
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── layout/ # Layout Komponenten
|
||||
│ │ │ │ ├── Navbar/
|
||||
│ │ │ │ ├── Sidebar/
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ ├── timeTracker/ # Zeiterfassung Komponenten
|
||||
│ │ │ │ ├── Timer/
|
||||
│ │ │ │ ├── EntryForm/
|
||||
│ │ │ │ └── ...
|
||||
│ │ │ └── ...
|
||||
│ │ ├── hooks/ # Custom React Hooks
|
||||
│ │ │ ├── useAuth.ts
|
||||
│ │ │ ├── useTimeTracking.ts
|
||||
│ │ │ └── ...
|
||||
│ │ ├── providers/ # Context Provider
|
||||
│ │ │ ├── AuthProvider.tsx
|
||||
│ │ │ ├── ThemeProvider.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ └── pages/ # Page Components (für App Router)
|
||||
│ │ ├── DashboardPage.tsx
|
||||
│ │ ├── TimeTrackingPage.tsx
|
||||
│ │ └── ...
|
||||
│ ├── utils/ # Utilities
|
||||
│ │ ├── fp/ # Funktionale Programmierung (FPTS)
|
||||
│ │ │ ├── option.ts
|
||||
│ │ │ ├── result.ts
|
||||
│ │ │ └── ...
|
||||
│ │ ├── date/ # Datumsfunktionen
|
||||
│ │ │ └── dateUtils.ts
|
||||
│ │ ├── formatting/ # Formattierung
|
||||
│ │ │ ├── numberFormat.ts
|
||||
│ │ │ └── ...
|
||||
│ │ └── validation/ # Validierung
|
||||
│ │ └── validators.ts
|
||||
│ ├── types/ # TypeScript Typendefinitionen
|
||||
│ │ ├── api.ts # API Response/Request Typen
|
||||
│ │ ├── auth.ts # Auth Typen
|
||||
│ │ └── ...
|
||||
│ └── styles/ # Globale Styles
|
||||
│ ├── globals.css
|
||||
│ └── theme.ts
|
||||
├── docu/ # Frontend-spezifische Dokumentation
|
||||
│ ├── component_library.md
|
||||
│ ├── state_management.md
|
||||
│ └── ...
|
||||
├── next.config.js
|
||||
├── tailwind.config.js
|
||||
├── tsconfig.json
|
||||
├── package.json
|
||||
└── README.md
|
||||
```
|
40
docu/general_overview.md
Normal file
40
docu/general_overview.md
Normal file
@ -0,0 +1,40 @@
|
||||
# General Overview
|
||||
|
||||
## Technology Stack
|
||||
|
||||
### Backend
|
||||
- Go with fp-go
|
||||
- PostgreSQL with ORM (GORM or Bun)
|
||||
- Swagger/OpenAPI
|
||||
- JWT-based Authentication
|
||||
|
||||
### Frontend
|
||||
- Next.js with fp-ts
|
||||
- React and Tailwind CSS
|
||||
- Responsive Webdesign
|
||||
- Progressive Web App (PWA)
|
||||
|
||||
## Multi-Tenancy & Roles
|
||||
- **Multi-Tenancy**: Isolation of data per company (tenant).
|
||||
- **Roles**: Admin, Company-Admin, Manager, Auditor, User.
|
||||
|
||||
## Data Models
|
||||
- **Company** (Tenant)
|
||||
- **User** (with roles, hourly rate)
|
||||
- **Customer**
|
||||
- **Project** (with customer reference)
|
||||
- **Activity** (billing rate)
|
||||
- **Booking** (time, user, project, activity, optional description, billability 0-100%)
|
||||
|
||||
## Functional Requirements
|
||||
### Version 1
|
||||
- Master data management (customers, projects, activities, users)
|
||||
- Time tracking with start/stop function and parameter inheritance from the last booking
|
||||
- Clear dashboard with recent bookings and tracker
|
||||
- Aggregated reports by period, project, customer, employee with PDF export
|
||||
- Graphical dashboards (diagrams)
|
||||
|
||||
### Version 2
|
||||
- Project management with sprints, tasks
|
||||
- Kanban boards for task management
|
||||
- Direct linking of tasks with time bookings
|
92
docu/llm_guidance.md
Normal file
92
docu/llm_guidance.md
Normal file
@ -0,0 +1,92 @@
|
||||
# LLM Guidance for the Time Tracking Project
|
||||
|
||||
This document provides guidance for Large Language Models (LLMs) working on the Time Tracking and Management System.
|
||||
|
||||
## File Locations
|
||||
|
||||
Here's a guide to finding information within the project:
|
||||
|
||||
**Documentation:**
|
||||
|
||||
- **General Project Overview:** `docu/general_overview.md`
|
||||
- **Backend Architecture (Go):** `docu/backend_architecture.md`
|
||||
- **Frontend Architecture (Next.js):** `docu/frontend_architecture.md`
|
||||
- **Database Schema (PostgreSQL):** `docu/database_schema.md`
|
||||
- **Deployment and DevOps:** `docu/deployment_devops.md`
|
||||
- **Security and Privacy:** `docu/security_privacy.md`
|
||||
- **Extensibility and Integrations:** `docu/extensibility_integrations.md`
|
||||
- **This LLM Guidance Document:** `docu/llm_guidance.md`
|
||||
- **Top Level Documentation Index:** `docu/README.md`
|
||||
|
||||
**Code (Conceptual - see architecture documents for details):**
|
||||
|
||||
- **Backend (Go):** (Refer to `docu/backend_architecture.md` for the conceptual structure. Actual code structure may differ.)
|
||||
- **Conceptual File Locations:**
|
||||
- `backend-go/internal/domain/entities/`: Core domain entities (User, Company, Project, etc.)
|
||||
- `backend-go/internal/domain/repositories/`: Interfaces for data access.
|
||||
- `backend-go/internal/domain/services/`: Business logic implementation.
|
||||
- `backend-go/internal/infrastructure/persistence/`: Database interactions (GORM).
|
||||
- `backend-go/internal/interfaces/http/handlers/`: API endpoint handlers.
|
||||
- `backend-go/internal/interfaces/http/middleware/`: Authentication and tenant isolation middleware.
|
||||
- **Code Examples:**
|
||||
- `docu/code_examples/gorm_entities.go`: Example GORM entity definitions.
|
||||
- `docu/code_examples/fpgo_repository.go`: Example FPGO repository interface.
|
||||
- `docu/code_examples/fpgo_service.go`: Example FPGO service implementation.
|
||||
- `docu/code_examples/api_handler.go`: Example API handler.
|
||||
|
||||
- **Frontend (Next.js):** (Refer to `docu/frontend_architecture.md` for the conceptual structure. Actual code structure may differ.)
|
||||
- **Conceptual File Locations:**
|
||||
- `frontend-nextjs/pages/`: Application pages.
|
||||
- `frontend-nextjs/components/`: Reusable UI components.
|
||||
- `frontend-nextjs/lib/`: API interaction and helper functions.
|
||||
- `frontend-nextjs/types/`: TypeScript type definitions.
|
||||
- **Code Examples:**
|
||||
- `docu/code_examples/react_component.tsx`: Example React component.
|
||||
|
||||
**Important Note about Code Examples:** The files in `docu/code_examples/` are for illustrative purposes *only*. They do *not* represent a runnable project structure. Treat each file as an isolated example. The package declarations within these files (e.g., `package entities`, `package repositories`, `package main`) are conceptual and should be interpreted in the context of the described architecture, *not* as a literal directory structure. Do not attempt to run `go get` or similar commands based on these examples, as the necessary project structure and dependencies are not present.
|
||||
|
||||
## Rules and Guidelines
|
||||
|
||||
1. **Clean Architecture:** Adhere to Clean Architecture principles. Separate business logic (domain) from infrastructure concerns (database, UI).
|
||||
2. **Domain-Driven Design (DDD):** Use DDD concepts to model the domain accurately.
|
||||
3. **Multi-Tenancy:** Ensure all operations are scoped to the correct tenant (company). Use the `company_id` for data isolation.
|
||||
4. **FPGO and FPTS:** Favor functional programming paradigms in both Go (FPGO) and TypeScript (FPTS).
|
||||
5. **Modularity:** Keep code modular and well-organized.
|
||||
6. **Error Handling:** Implement robust error handling and validation.
|
||||
7. **Security:** Prioritize security. Use JWT for authentication and RBAC for authorization. Sanitize inputs to prevent injection attacks.
|
||||
8. **Testing:** Write unit and integration tests for all new code.
|
||||
9. **Documentation**: Keep the documentation up to date.
|
||||
10. **Conceptual Architecture**: The architecture files are a *concept*, not a final implementation.
|
||||
|
||||
## Ideas to Follow
|
||||
|
||||
- **Small, Focused Modules:** Break down tasks into small, well-defined modules.
|
||||
- **Descriptive Naming:** Use clear and descriptive names for variables, functions, and files.
|
||||
- **Comments:** Add comments to explain complex logic.
|
||||
- **Consistency:** Maintain consistent coding style and patterns.
|
||||
- **Leverage Libraries:** Use existing libraries (FPGO, FPTS, GORM, Gin, Axios, etc.) where appropriate.
|
||||
- **Ask for Clarification:** If unsure about any aspect of the project, use the `ask_followup_question` tool.
|
||||
- **Visually Appealing Design:** (Especially for Claude models) Strive for a visually appealing and user-friendly interface. Consider using appropriate colors, layout, and components.
|
||||
- **Prefer Replacements:** When making changes to existing files, favor the `replace_in_file` tool over `write_to_file` to minimize context usage and cost. Only use `write_to_file` for creating new files or making extensive, non-localized changes.
|
||||
|
||||
## Workflow for Limited Context
|
||||
|
||||
If you encounter context limitations or are instructed to work in smaller chunks, follow this workflow:
|
||||
|
||||
1. **Request a Summary:** If needed, ask for a brief summary of the current task and relevant file content.
|
||||
2. **Plan in Chunks:** Divide the task into smaller, manageable sub-tasks.
|
||||
3. **Focus on One Chunk:** Work on one sub-task at a time.
|
||||
4. **Use `replace_in_file`:** Make targeted changes using `replace_in_file`.
|
||||
5. **Iterate:** Repeat steps 3 and 4 for each sub-task.
|
||||
6. **Provide Context Briefing:** When moving to a new chunk or file, provide a concise summary of the previous work and the current objective. This helps maintain context across multiple interactions.
|
||||
|
||||
## Code Organization and Style
|
||||
|
||||
- **Functional File Division:** Divide functionalities logically into separate files. This improves readability, maintainability, and helps manage context size.
|
||||
- **Code Reusability:** Design code to be reusable and extensible. Anticipate future requirements and create components or functions that can be adapted for different purposes.
|
||||
- **Common Sense:** Apply general good coding practices, even if they seem obvious. This includes things like:
|
||||
- Using meaningful variable and function names.
|
||||
- Adding comments to explain non-obvious logic.
|
||||
- Handling edge cases and potential errors.
|
||||
- Keeping functions and components concise and focused.
|
||||
- Following consistent indentation and formatting.
|
6
docu/security_privacy.md
Normal file
6
docu/security_privacy.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Security and Data Privacy
|
||||
|
||||
- Tenant isolation
|
||||
- TLS encryption and encrypted storage of sensitive data
|
||||
- Audit logs (comprehensive logging)
|
||||
- GDPR compliant (data export, right to be forgotten)
|
Loading…
x
Reference in New Issue
Block a user