Some checks failed
Dev Build / build-test (pull_request) Failing after 2m4s
- Add dtos package with request/response structs
- Add repositories: Material, Filament, Printer, PrintJob, UsageLog
- Add services: FilamentService, PrinterService, PrintJobService
- Add handlers for all 5 resources with consistent error responses
- Wire all endpoints into Chi router under /api
- Validation on POST/PUT filament endpoints
- Filter/pagination support on list endpoints
- Soft-delete for filaments (DELETE /api/filaments/{id})
- go build ./... && go vet ./... → PASS
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package repositories
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/CubeCraft-Creations/Extrudex/backend/internal/models"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// UsageLogRepository handles database queries for usage_logs.
|
|
type UsageLogRepository struct {
|
|
pool *pgxpool.Pool
|
|
}
|
|
|
|
// NewUsageLogRepository creates a UsageLogRepository backed by the given pool.
|
|
func NewUsageLogRepository(pool *pgxpool.Pool) *UsageLogRepository {
|
|
return &UsageLogRepository{pool: pool}
|
|
}
|
|
|
|
// UsageLogFilter holds query parameters for listing usage logs.
|
|
type UsageLogFilter struct {
|
|
SpoolID *int // filter by filament_spool_id
|
|
JobID *int // filter by print_job_id
|
|
Limit int
|
|
Offset int
|
|
}
|
|
|
|
// GetAll returns usage logs matching the given filters, with pagination.
|
|
func (r *UsageLogRepository) GetAll(ctx context.Context, filter UsageLogFilter) ([]models.UsageLog, int, error) {
|
|
conditions := []string{"1=1"}
|
|
args := []interface{}{}
|
|
argIdx := 1
|
|
|
|
if filter.SpoolID != nil {
|
|
conditions = append(conditions, fmt.Sprintf("ul.filament_spool_id = $%d", argIdx))
|
|
args = append(args, *filter.SpoolID)
|
|
argIdx++
|
|
}
|
|
if filter.JobID != nil {
|
|
conditions = append(conditions, fmt.Sprintf("ul.print_job_id = $%d", argIdx))
|
|
args = append(args, *filter.JobID)
|
|
argIdx++
|
|
}
|
|
|
|
whereClause := "WHERE " + fmt.Sprintf("%s", conditions[0])
|
|
for _, c := range conditions[1:] {
|
|
whereClause += " AND " + c
|
|
}
|
|
|
|
// Count.
|
|
var total int
|
|
countQuery := "SELECT COUNT(*) FROM usage_logs ul " + whereClause
|
|
if err := r.pool.QueryRow(ctx, countQuery, args...).Scan(&total); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Query with pagination.
|
|
dataQuery := `SELECT id, print_job_id, filament_spool_id, mm_extruded,
|
|
grams_used, cost_usd, logged_at, created_at
|
|
FROM usage_logs ul
|
|
` + whereClause +
|
|
" ORDER BY ul.logged_at DESC" +
|
|
fmt.Sprintf(" LIMIT $%d OFFSET $%d", argIdx, argIdx+1)
|
|
|
|
dataArgs := make([]interface{}, len(args))
|
|
copy(dataArgs, args)
|
|
dataArgs = append(dataArgs, filter.Limit, filter.Offset)
|
|
|
|
rows, err := r.pool.Query(ctx, dataQuery, dataArgs...)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var logs []models.UsageLog
|
|
for rows.Next() {
|
|
var l models.UsageLog
|
|
if err := rows.Scan(
|
|
&l.ID, &l.PrintJobID, &l.FilamentSpoolID,
|
|
&l.MMExtruded, &l.GramsUsed, &l.CostUSD,
|
|
&l.LoggedAt, &l.CreatedAt,
|
|
); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
logs = append(logs, l)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if logs == nil {
|
|
logs = []models.UsageLog{}
|
|
}
|
|
|
|
return logs, total, nil
|
|
}
|