feat: portfolio of all my projects

/cartera (and GraphQL portfolio, REST /api/me/portfolio, MCP
get_portfolio) shows every active project I belong to (not archived, not
as a guest) at a glance: open, overdue, blocked and stuck tickets, the
sprint under way and whether it gets there, planned releases with their
forecast, and the open epics with their progress. It reuses the
dashboard's computations. A release with no tickets now reads «Sin
tickets» instead of «Todo hecho», here and on the dashboard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 18:27:46 +02:00
parent 8bf7d47b2e
commit affce615a7
35 changed files with 1603 additions and 80 deletions

View File

@@ -6,6 +6,7 @@ import {
Project,
ProjectAnalytics,
ProjectInsights,
PortfolioProject,
ProjectSettings,
ProjectsGateway,
ProjectStats,
@@ -22,6 +23,7 @@ import {
MyProjectsDocument,
ProjectAnalyticsDocument,
ProjectInsightsDocument,
PortfolioDocument,
ProjectDocument,
ProjectStatsDocument,
PublicProjectsDocument,
@@ -32,6 +34,7 @@ import {
import { GraphqlOperations } from './graphql-operations';
import {
toCommandResult,
toIssueSummary,
toProject,
toSettingsInput,
toStats,
@@ -65,6 +68,21 @@ export class GraphqlProjectsGateway extends ProjectsGateway {
.pipe(map((d) => toStats(d.project.stats)));
}
portfolio(): Observable<PortfolioProject[]> {
return this.gql.query(PortfolioDocument, {}).pipe(
map((d) =>
d.portfolio.map((p) => ({
...(p as unknown as PortfolioProject),
epics: p.epics.map((e) => ({
issue: toIssueSummary(e.issue),
progress: { ...e.progress },
links: [],
})),
})),
),
);
}
insights(
projectId: string,
since: string | null,