46 lines
1.1 KiB
Go
46 lines
1.1 KiB
Go
package provider
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"orchestra/internal/domain"
|
|
)
|
|
|
|
type Sink interface{ Append(domain.Event) error }
|
|
type Provider interface {
|
|
Ingest(io.Reader, Sink) (int, error)
|
|
}
|
|
|
|
// JSONL treats each line as an external task object. Replaying the same input
|
|
// is safe because the store deduplicates the stable source/external_id key.
|
|
type JSONL struct{}
|
|
|
|
func (JSONL) Ingest(r io.Reader, sink Sink) (int, error) {
|
|
sc := bufio.NewScanner(r)
|
|
count := 0
|
|
line := 0
|
|
for sc.Scan() {
|
|
line++
|
|
raw := sc.Bytes()
|
|
if len(raw) == 0 {
|
|
continue
|
|
}
|
|
var p map[string]any
|
|
if err := json.Unmarshal(raw, &p); err != nil {
|
|
return count, fmt.Errorf("line %d: %w", line, err)
|
|
}
|
|
if err := domain.ValidateCreated(p); err != nil {
|
|
return count, fmt.Errorf("line %d: %w", line, err)
|
|
}
|
|
b, _ := json.Marshal(p)
|
|
e := domain.Event{ID: domain.NewID(), Type: "TaskCreated", TaskID: domain.NewID(), Version: 1, Payload: b}
|
|
if err := sink.Append(e); err != nil {
|
|
return count, fmt.Errorf("line %d: %w", line, err)
|
|
}
|
|
count++
|
|
}
|
|
return count, sc.Err()
|
|
}
|