Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

04 — Information Architecture (Communication Module)

Screen tree, navigation, and content model. Route conventions follow 00-shared/05.


1. Route tree

/announcements                      Announcement feed (recipient)
├── /announcements/:id              Detail (sheet on mobile)  (forward-looking: no GET :id API)
│   └── attachments                 external/browser
├── /announcements/compose          Composer (author only)
│   └── audience picker             nested sheet
├── /announcements/mine             Author's own list (drafts + published)
│   └── /announcements/:id/reads    Read receipts (author only)
/threads                            Conversation list
└── /threads/:id                    Thread detail (messages)

All routes live under the authenticated shell; entry from the dashboard "Communication" hub and from global search (docs/IMPLEMENTATION_PLAN.md:174 — announcements indexed).

2. Content model (from backend, announcement.schema.ts:31-53)

Announcement
├── title: String (required, trimmed)             :33-34
├── body: String (required, trimmed)              :36-37
├── audience: { type: enum, value?: string|string[] }  :39-40 (enum :7-13)
│   └── all | role | grade | section | custom
├── targetUserIds: ObjectId[] (ref User, default [])    :42-43
├── published: Boolean (default false)            :45-46   ← draft when false
├── publishedAt?: Date                            :48-49
├── readBy?: [{ userId, readAt }]                 :51-52
└── + BaseSchema (tenantId, timestamps, soft-delete)

Index: { tenantId: 1, published: 1, createdAt: -1 } (:57) — the feed's natural sort/filter shape.

3. Audience taxonomy

AudienceType (announcement.schema.ts:7-13)value shapeResolution (announcement.service.ts:109-148)
allnone[] — broadcast marker, targets empty :144-146
rolestring (e.g. teacher)org members roles: value, status: 'active' → userIds :114-119
gradestring (grade name)gradeRepo.findOne({name}) → students of grade :120-125
sectionstring (section name)sectionRepo.findOne({name}) → students of section :126-135
customstring[] userIdsdirect ObjectId map :136-143

4. State diagram (document lifecycle)

draft (published:false) ──publish──► published (publishedAt set, targets resolved)
        ▲                              │
        │ re-edit (planned)            │  read (POST :id/read → $addToSet receipt)
        │                              ▼
  no update route today         published + readBy[...]
                                   │
                                   ▼
        archived/expired (planned — no field in schema)

5. Module boundaries

  • Announcements read across modules: academics (grade/section), students, rbac (OrganizationMember) — communication.module.ts:38-40, announcement.service.ts:6-8,25-26.
  • Writes go out via domain events: AnnouncementCreated, AnnouncementPublished (communication-events.ts:9-13); queue fan-out (planned)event-queue-map.ts has no Announcement routes today.
  • Notifications engine owns delivery channels (studylyon-blueprint/04-Modules/Notifications.md) — out of scope here.