04 — Information Architecture (Communication Module)
- 1. Route tree
- 2. Content model (from backend,
announcement.schema.ts:31-53) - 3. Audience taxonomy
- 4. State diagram (document lifecycle)
- 5. Module boundaries
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 shape | Resolution (announcement.service.ts:109-148) |
|---|---|---|
all | none | [] — broadcast marker, targets empty :144-146 |
role | string (e.g. teacher) | org members roles: value, status: 'active' → userIds :114-119 |
grade | string (grade name) | gradeRepo.findOne({name}) → students of grade :120-125 |
section | string (section name) | sectionRepo.findOne({name}) → students of section :126-135 |
custom | string[] userIds | direct 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.tshas no Announcement routes today. - Notifications engine owns delivery channels (
studylyon-blueprint/04-Modules/Notifications.md) — out of scope here.