world

package
v1.786.131 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package world mounts the Hanzo Cloud "World" news data plane: a per-org, per-project intelligence feed that normalizes GDELT + host-allowlisted RSS/Atom into one NewsItem stream, applies the project's keyword/region/source filter, and serves it over REST + SSE. It is the Go backend for the World monitor frontend (hanzoai/world), replacing that app's Vercel edge functions (api/gdelt-doc.js, api/rss-proxy.js) with an org-scoped, in-binary subsystem.

Surface (all org/project-scoped; /v1 only):

GET /v1/world/news       merged, filtered, freshest-first feed -> {items:[…]}
GET /v1/world/pipeline   per-project pipeline config (read)    -> {…}
PUT /v1/world/pipeline   per-project pipeline config (write)   -> {…}
GET /v1/world/stream     SSE live refresh (ZAP-native)         -> event: news

TENANT ISOLATION is enforced SERVER-SIDE on every request. The (org, project) tuple is principal.Tenant + principal.Project (the values SanitizeIdentity minted from the VALIDATED bearer, HIP-0026) — never a query param, body, or client header. Every store statement carries `WHERE org=? AND project=?`; the SSE bus filters on org and the stream loop drops other projects. A request with no validated principal is a 403.

SECURITY. The RSS fetcher is an SSRF boundary: a feed URL's host must be in the ported rss-proxy.js allowlist (allowlist.go), enforced at BOTH the PUT write boundary and at fetch time, including on redirect targets (client CheckRedirect).

Order 142 binds /v1/world/* ahead of the AI /v1/* catch-all (150).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Mount

func Mount(app *zip.App, deps cloud.Deps) error

Mount registers the world surface on app per HIP-0106.

func Shutdown

func Shutdown() error

Shutdown closes the SSE bus (unblocking every open stream) and the pipeline store. Idempotent — safe to call when nothing is mounted.

Types

type Filters

type Filters struct {
	Regions  []string `json:"regions"`
	Keywords []string `json:"keywords"`
	Sources  []string `json:"sources"`
}

Filters narrows the merged news stream. Each axis is an OR-set of terms; a non-empty axis is an AND predicate against the item (empty axis = pass-through). Keywords ALSO seed the GDELT queries, so it is both a fetch input (fresh keyword-matched articles) and a post-merge filter.

type NewsItem

type NewsItem struct {
	Source  string `json:"source"`
	Title   string `json:"title"`
	Link    string `json:"link"`
	PubDate string `json:"pubDate"` // RFC3339 UTC, or "" when the upstream gave no parseable date
	Lang    string `json:"lang,omitempty"`
	Image   string `json:"image,omitempty"`
	Tone    string `json:"tone,omitempty"`
}

NewsItem is the normalized, source-agnostic shape every upstream (GDELT, RSS, Atom) is projected into and the wire contract for GET /v1/world/news.

type Pipeline

type Pipeline struct {
	Org       string
	Project   string
	Feeds     []string
	Filters   Filters
	CreatedAt int64
	UpdatedAt int64
}

Pipeline is the persisted per-(org,project) news pipeline config. Feeds are host-allowlisted RSS/Atom URLs; Filters narrows the merged result.

type PipelineStore

type PipelineStore struct {
	// contains filtered or unexported fields
}

PipelineStore is the world pipeline metastore over one SQLite file ({DataDir}/world.db). Tenancy is the (org, project) key.

func (*PipelineStore) Close

func (s *PipelineStore) Close() error

Close closes the underlying database.

func (*PipelineStore) Get

func (s *PipelineStore) Get(ctx context.Context, org, project string) (Pipeline, error)

Get returns the persisted pipeline for (org, project), or errNotFound when the org has never written a pipeline for that project (the caller then serves the default pipeline).

func (*PipelineStore) Put

func (s *PipelineStore) Put(ctx context.Context, p Pipeline) (Pipeline, error)

Put upserts the feeds + filters for (org, project). It is idempotent on the composite key and preserves created_at across updates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL