sources: {
[name: string]: {
bridge: string// required — npm package name of the bridge// Any additional fields are passed through to the bridge constructor.// For bridge-postgres, only the connection URL is needed — the service// resolves the stored credentials at ingest time.
}
}
interfaceFieldConfig {
type: 'text' | 'number' | 'boolean' | 'date' | 'json' | 'enum' | 'relation'searchable?: boolean | { weight: number } // include in vector embeddingsprimaryKey?: boolean// mark this field as the PKfrom?: string// source column name if different from field nametransform?: TransformSpec | TransformSpec[] // value transform chain
}
feeds is Record<feedName, FeedConfig>. Each named entry compiles
to beam.<lens>.feed.<name>(...) plus a subscribe() and explain(). Every
feed gets its own access grant under grants.feed[name].
engagement.lens is always a sibling lens declared in the same
environment. The read flows through that lens's bridge and respects its
grants.query (so pk_ callers without access see engagement=0; sk_
bypasses). There is no raw-table path: a likes / views / bookmarks
table must be declared as a lens before feeds can reference it.
Pick relation when your lens already declares a relations entry
pointing at the engagement lens — the join columns are derived from
that relation's on map, so the config stays DRY. Otherwise provide an
explicit join: { local, foreign } with both sides referring to declared
lens fields.