atmo.rsvp
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 92 lines 3.3 kB view raw
1import type { ContrailConfig } from '@atmo-dev/contrail'; 2import { SPACE_TYPE } from './spaces/config'; 3 4export const config: ContrailConfig = { 5 namespace: 'rsvp.atmo', 6 // Enable the rsvp.atmo.notifyOfUpdate endpoint. The client calls it after 7 // writing records to the PDS so contrail re-fetches and indexes them 8 // immediately instead of waiting for the jetstream. 9 notify: true, 10 // `spaces` is declared statically so `pnpm generate` emits the `rsvp.atmo.space.*` 11 // lexicons. The real serviceDid is injected at runtime in `$lib/contrail/index.ts` 12 // via `getSpacesConfig()` — generate doesn't serialize it. 13 spaces: { type: SPACE_TYPE, serviceDid: 'did:web:placeholder' }, 14 permissionSet: { 15 title: 'Atmo Events', 16 description: 'Manage your private events and rsvps.' 17 // NOTE: permission-set lexicons can only reference NSIDs under their own 18 // namespace (`rsvp.atmo.*`). Repo writes for `community.lexicon.*` and 19 // blob uploads are declared as standalone `scope.repo(...)` / 20 // `scope.blob(...)` entries in `atproto/settings.ts`, not here. 21 }, 22 collections: { 23 event: { 24 collection: 'community.lexicon.calendar.event', 25 queryable: { 26 mode: {}, 27 name: {}, 28 status: {}, 29 description: {}, 30 'preferences.showInDiscovery': {}, 31 startsAt: { type: 'range' }, 32 endsAt: { type: 'range' }, 33 createdAt: { type: 'range' } 34 }, 35 searchable: ['mode', 'name', 'status', 'description'], 36 relations: { 37 rsvps: { 38 collection: 'rsvp', 39 groupBy: 'status', 40 groups: { 41 going: 'community.lexicon.calendar.rsvp#going', 42 interested: 'community.lexicon.calendar.rsvp#interested', 43 notgoing: 'community.lexicon.calendar.rsvp#notgoing' 44 } 45 } 46 }, 47 pipelineQueries: { 48 // Endpoint: rsvp.atmo.event.listDiscoverable 49 // Same shape as listRecords, but filters out unlisted events 50 // (preferences.showInDiscovery === false). Missing field defaults 51 // to true, so pre-existing records without `preferences` are included. 52 listDiscoverable: async () => ({ 53 conditions: [ 54 `(json_extract(r.record, '$.preferences.showInDiscovery') IS NULL 55 OR json_extract(r.record, '$.preferences.showInDiscovery') != 0)` 56 ] 57 }) 58 } 59 }, 60 rsvp: { 61 collection: 'community.lexicon.calendar.rsvp', 62 queryable: { 63 status: {}, 64 'subject.uri': {}, 65 createdAt: { type: 'range' } 66 }, 67 references: { 68 event: { 69 collection: 'event', 70 field: 'subject.uri' 71 } 72 } 73 } 74 // `follow` (app.bsky.graph.follow) is auto-added by contrail 0.5+ when 75 // `feeds` is configured: discover:false, subjectField:'subject' (so only 76 // follows whose subject is already in identities are indexed). 77 }, 78 feeds: { 79 // Exposed as rsvp.atmo.getFeed?feed=network&actor=<did>&collection=<nsid>. 80 // Powers the home-page "from people you follow" surface. 81 network: { 82 // Per-target caps so RSVPs (high-volume) can't squeeze events 83 // (low-volume) out of the cap. Bumped above the default 200 because 84 // most RSVPs in feed_items refer to past events, and we want enough 85 // breathing room to find recent ones after the JS-side filter. 86 targets: [ 87 { collection: 'event', maxItems: 200 }, 88 { collection: 'rsvp', maxItems: 1000 } 89 ] 90 } 91 } 92};