feat(guild-messaging): add gap-detection metadata for seq backfill responses
This commit is contained in:
@@ -132,6 +132,26 @@ export class MessagingController {
|
||||
? Math.min(requestedLimit, MAX_PAGE_LIMIT)
|
||||
: DEFAULT_PAGE_LIMIT;
|
||||
|
||||
if (from > to) {
|
||||
return {
|
||||
items: [],
|
||||
page: {
|
||||
seqFrom: from,
|
||||
seqTo: to,
|
||||
limit: safeLimit,
|
||||
returned: 0,
|
||||
hasMore: false,
|
||||
nextExpectedSeq: from,
|
||||
highestCommittedSeq: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const channel = await this.channelRepo.findOne({ where: { id: channelId } });
|
||||
if (!channel) {
|
||||
throw new NotFoundException('channel not found');
|
||||
}
|
||||
|
||||
const qb = this.messageRepo
|
||||
.createQueryBuilder('m')
|
||||
.where('m.channelId = :channelId', { channelId })
|
||||
@@ -143,6 +163,16 @@ export class MessagingController {
|
||||
const rows = await qb.limit(safeLimit).getMany();
|
||||
const items = rows.map((m) => this.toView(m));
|
||||
|
||||
let nextExpectedSeq = from;
|
||||
for (const row of rows) {
|
||||
if (row.seq > nextExpectedSeq) {
|
||||
break;
|
||||
}
|
||||
if (row.seq === nextExpectedSeq) {
|
||||
nextExpectedSeq += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
items,
|
||||
page: {
|
||||
@@ -151,6 +181,8 @@ export class MessagingController {
|
||||
limit: safeLimit,
|
||||
returned: items.length,
|
||||
hasMore: total > items.length,
|
||||
nextExpectedSeq,
|
||||
highestCommittedSeq: channel.lastSeq,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
- [x] seq 分配改为 DB 原子方案(避免并发冲突)
|
||||
|
||||
### 2.3 一致性与回补
|
||||
- [ ] 回补接口:`seq_from/seq_to`
|
||||
- [ ] 断片检测辅助响应字段(next_expected_seq 等)
|
||||
- [x] 回补接口:`seq_from/seq_to`
|
||||
- [x] 断片检测辅助响应字段(next_expected_seq 等)
|
||||
- [ ] 幂等键支持(写接口)
|
||||
|
||||
### 2.4 实时通信(MVP 后半)
|
||||
|
||||
Reference in New Issue
Block a user