feat: expand companion platform, device controls, and memoir workflows
ci / verify (push) Canceled after 0s
ci / verify (push) Canceled after 0s
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package callmemory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"data-terminal-cloud/internal/outbox"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// Story review is independent of automatic Viking memory extraction. Schedule
|
||||
// only drained, authorized calls; late subtitles get a new revision and event.
|
||||
func (s *Service) enqueueDirectStories(ctx context.Context, tx pgx.Tx) error {
|
||||
rows, err := tx.Query(ctx, `SELECT c.id::text,c.tenant_id::text,c.transcript_revision,c.privacy_epoch
|
||||
FROM call_session c WHERE c.ended_at IS NOT NULL AND c.transcript_state IN ('COMPLETE','PARTIAL')
|
||||
AND c.transcript_revision>0 AND c.budget_snapshot->>'protocol'='DIRECT-CHAT-1'
|
||||
AND c.budget_snapshot->>'story_extraction_allowed'='true' AND call_story_authorized(c.id)
|
||||
AND NOT EXISTS(SELECT 1 FROM call_story_extraction e WHERE e.session_id=c.id AND e.transcript_revision=c.transcript_revision AND e.privacy_epoch=c.privacy_epoch)
|
||||
AND NOT EXISTS(SELECT 1 FROM outbox_event o WHERE o.aggregate_id=c.id AND o.event_type='call.story_extraction_requested'
|
||||
AND o.deduplication_key='call-story-v1:'||c.id::text||':'||c.transcript_revision::text||':'||c.privacy_epoch::text)
|
||||
ORDER BY c.ended_at,c.id LIMIT 20`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
type pending struct {
|
||||
session, tenant string
|
||||
revision, epoch int64
|
||||
}
|
||||
items := []pending{}
|
||||
for rows.Next() {
|
||||
var item pending
|
||||
if err = rows.Scan(&item.session, &item.tenant, &item.revision, &item.epoch); err != nil {
|
||||
rows.Close()
|
||||
return err
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
err = rows.Err()
|
||||
rows.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range items {
|
||||
key := fmt.Sprintf("call-story-v1:%s:%d:%d", item.session, item.revision, item.epoch)
|
||||
payload, _ := json.Marshal(map[string]int64{"generation_version": item.revision, "privacy_epoch": item.epoch})
|
||||
if _, err = outbox.NewStore(s.pool).Enqueue(ctx, tx, outbox.NewEvent{
|
||||
TenantID: &item.tenant, AggregateType: "call_session", AggregateID: item.session,
|
||||
EventType: "call.story_extraction_requested", DeduplicationKey: &key, Payload: payload,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user