feat: a home page with life
Greeting and summary of the day, the coming week, the latest across my projects, who is online now, the week in numbers (mine and the team's, with a streak), sprints under way, «Retomar», project cards with their activity, what to pick up when nothing is mine and first steps for newcomers. REST (GET /api/me/home), GraphQL (myHome) and MCP (get_my_week). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -614,6 +614,47 @@ export class MongoFindActivityRepository extends FindActivityRepository {
|
||||
.lean<ActivityDoc[]>();
|
||||
return docs.map(fromDoc);
|
||||
}
|
||||
|
||||
async findAcross(
|
||||
projectIds: string[],
|
||||
limit: number,
|
||||
): Promise<ActivityReadModel[]> {
|
||||
if (!projectIds.length) return [];
|
||||
const docs = await this.activity
|
||||
.find({ projectId: { $in: projectIds } })
|
||||
.sort({ occurredAt: -1 })
|
||||
.limit(limit)
|
||||
.lean<ActivityDoc[]>();
|
||||
return docs.map(fromDoc);
|
||||
}
|
||||
|
||||
async dailyCounts(
|
||||
projectIds: string[],
|
||||
fromDay: string,
|
||||
): Promise<{ projectId: string; day: string; count: number }[]> {
|
||||
if (!projectIds.length) return [];
|
||||
const rows = await this.activity.aggregate<{
|
||||
_id: { projectId: string; day: string };
|
||||
count: number;
|
||||
}>([
|
||||
{
|
||||
$match: {
|
||||
projectId: { $in: projectIds },
|
||||
occurredAt: { $gte: fromDay },
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
projectId: '$projectId',
|
||||
day: { $substrCP: ['$occurredAt', 0, 10] },
|
||||
},
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
]);
|
||||
return rows.map((r) => ({ ...r._id, count: r.count }));
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
|
||||
Reference in New Issue
Block a user