Artifact and media metadata were previously reconstructed from job result refs and JSON sidecar files. This change regularizes metadata into SQLite, keeps filesystem blobs in place, and preserves backward compatibility via lazy fallback and backfill from existing job refs and JSON metadata. Constraint: Blob storage remains on the local filesystem in this phase Rejected: Migrate blobs into SQLite | larger scope and worse operational profile for current media sizes Rejected: Hard cutover without fallback | unsafe for historical data already on the test server Confidence: medium Scope-risk: moderate Directive: Treat SQLite as the metadata source of truth; JSON sidecars are compatibility fallback only Tested: go test ./...; deployed to test server 101.42.99.35; verified /v1/artifacts, /v1/artifacts/:id, signed media URL 200, unsigned content 401 Not-tested: Full historical backfill sweep over all existing artifact rows under production-sized data volume
141 lines
5.1 KiB
Go
141 lines
5.1 KiB
Go
package server
|
|
|
|
import "time"
|
|
|
|
type envelope map[string]any
|
|
|
|
type user struct {
|
|
ID string `json:"id"`
|
|
Email string `json:"email"`
|
|
Name string `json:"name"`
|
|
Scopes []string `json:"scopes,omitempty"`
|
|
}
|
|
|
|
type session struct {
|
|
Token string
|
|
UserID string
|
|
UpstreamKey string
|
|
User user
|
|
CreatedAt time.Time
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
type authSessionView struct {
|
|
User user `json:"user"`
|
|
SessionKey string `json:"session_key,omitempty"`
|
|
UpstreamKeyMasked string `json:"upstream_key_masked,omitempty"`
|
|
}
|
|
|
|
type skill struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Tags []string `json:"tags"`
|
|
Version string `json:"version"`
|
|
InputSchema map[string]any `json:"input_schema,omitempty"`
|
|
OutputSchema map[string]any `json:"output_schema,omitempty"`
|
|
ModelType string `json:"model_type"`
|
|
RouteKey string `json:"route_key,omitempty"`
|
|
EstimatedDurationS int `json:"estimated_duration_s"`
|
|
}
|
|
|
|
type jobError struct {
|
|
Code string `json:"code,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
Details map[string]any `json:"details,omitempty"`
|
|
}
|
|
|
|
type resultRef struct {
|
|
Kind string `json:"kind"`
|
|
URL string `json:"url,omitempty"`
|
|
DataURL string `json:"data_url,omitempty"`
|
|
LocalPath string `json:"local_path,omitempty"`
|
|
MediaID string `json:"media_id,omitempty"`
|
|
Filename string `json:"filename,omitempty"`
|
|
ContentType string `json:"content_type,omitempty"`
|
|
SizeBytes int64 `json:"size_bytes,omitempty"`
|
|
Visibility string `json:"visibility,omitempty"`
|
|
SHA256 string `json:"sha256,omitempty"`
|
|
StorageStatus string `json:"storage_status,omitempty"`
|
|
}
|
|
|
|
type job struct {
|
|
JobID string `json:"job_id"`
|
|
Status string `json:"status"`
|
|
SkillID string `json:"skill_id,omitempty"`
|
|
ModelID string `json:"model_id,omitempty"`
|
|
RouteKey string `json:"route_key,omitempty"`
|
|
Input map[string]any `json:"input,omitempty"`
|
|
ProjectID string `json:"project_id,omitempty"`
|
|
Priority string `json:"priority,omitempty"`
|
|
IdempotencyKey string `json:"idempotency_key,omitempty"`
|
|
CreatedAt string `json:"created_at,omitempty"`
|
|
StartedAt string `json:"started_at,omitempty"`
|
|
FinishedAt string `json:"finished_at,omitempty"`
|
|
ArtifactIDs []string `json:"artifact_ids,omitempty"`
|
|
Error *jobError `json:"error,omitempty"`
|
|
Usage map[string]any `json:"usage,omitempty"`
|
|
UserID string `json:"user_id,omitempty"`
|
|
ExecMode string `json:"exec_mode,omitempty"`
|
|
NewAPITaskID string `json:"newapi_task_id,omitempty"`
|
|
SessionID string `json:"-"`
|
|
ResultRefs []resultRef `json:"-"`
|
|
UpstreamKey string `json:"-"`
|
|
}
|
|
|
|
type logEntry struct {
|
|
TS string `json:"ts"`
|
|
Level string `json:"level"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
type artifact struct {
|
|
ID string `json:"id"`
|
|
JobID string `json:"job_id"`
|
|
ProjectID string `json:"project_id,omitempty"`
|
|
MediaID string `json:"media_id,omitempty"`
|
|
Filename string `json:"filename"`
|
|
ContentType string `json:"content_type"`
|
|
SizeBytes int64 `json:"size_bytes"`
|
|
CreatedAt string `json:"created_at"`
|
|
ExpiresAt string `json:"expires_at"`
|
|
URL string `json:"url,omitempty"`
|
|
Visibility string `json:"visibility,omitempty"`
|
|
SHA256 string `json:"sha256,omitempty"`
|
|
StorageStatus string `json:"storage_status,omitempty"`
|
|
SourceSkillID string `json:"source_skill_id,omitempty"`
|
|
SourceModelID string `json:"source_model_id,omitempty"`
|
|
SourceRouteKey string `json:"source_route_key,omitempty"`
|
|
SourceInput map[string]any `json:"source_input,omitempty"`
|
|
PromptText string `json:"prompt_text,omitempty"`
|
|
Usage map[string]any `json:"usage,omitempty"`
|
|
Ref resultRef `json:"-"`
|
|
}
|
|
|
|
type media struct {
|
|
ID string `json:"id"`
|
|
ArtifactID string `json:"artifact_id,omitempty"`
|
|
ProjectID string `json:"project_id,omitempty"`
|
|
Filename string `json:"filename"`
|
|
ContentType string `json:"content_type"`
|
|
SizeBytes int64 `json:"size_bytes"`
|
|
CreatedAt string `json:"created_at"`
|
|
URL string `json:"url"`
|
|
Visibility string `json:"visibility,omitempty"`
|
|
SHA256 string `json:"sha256,omitempty"`
|
|
}
|
|
|
|
type project struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type model struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Provider string `json:"provider"`
|
|
Capabilities []string `json:"capabilities"`
|
|
Pricing map[string]any `json:"pricing"`
|
|
}
|