a32c937765cc4993ed292e0db76ca1b600df49e4
The Redis consumer used to leave a failed event pending and go on to the next ones, retrying it only at the next start. With Mongo down for a while, a later change of the same ticket was then projected first, and the version check dropped the earlier one for good (a status change could vanish from the read model), besides the read side lagging until a restart. Now a failed event is retried in place, waiting longer each time (up to 30 s), and the next one waits for it. Failures of the infrastructure (Mongo, Redis, the network: isTransientError) wait as long as it takes, so the read side catches up by itself; an event that keeps failing on its own goes, after 5 attempts, to <stream>:dead with its error, so it does not hold up the rest. GET /api/health reports the way from write to read (events waiting in the outbox, pending to be projected, set aside) and says `degraded`, still with 200, when something is stuck. Tried for real: with Mongo stopped, two status changes went in; the first failed to project with ECONNREFUSED, and once Mongo was back the ticket's history had both steps, in order, without restarting the API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TaskStream
Alternativa a Jira para equipos de desarrollo: proyectos, tickets (bugs, features, cambios de UI, tareas y QA), releases, comentarios y relaciones entre tickets, en tiempo real.
- API: NestJS + GraphQL y REST con OpenAPI (Swagger, para otras apps), arquitectura hexagonal, CQRS y event sourcing (escritura en PostgreSQL, lectura en MongoDB, Redis entre ambas).
- Web: Angular 22 + NgRx Signals (patrón de eventos) +
@pi/ui, con la misma arquitectura. - Usuarios: los gestiona Pireon.
Empezar
docker compose up -d --build # web en http://localhost:8080
Para entrar hacen falta los clientes OAuth de Pireon en .env: uno authorization_code (PIREON_CLIENT_ID /
_SECRET, «Entrar con Pireon») y uno password (PIREON_PASSWORD_CLIENT_ID / _SECRET, email y contraseña). Ver
Autenticación. Para desarrollar:
npm install # @pi/ui necesita el token del Nexus de Pireon en ~/.npmrc
docker compose up -d postgres mongo redis
cp .env.example .env
npx nx serve api # http://localhost:3000/graphql · REST: /api/docs
npx nx serve web # http://localhost:4200
Documentación
| Visión general | Funcionalidades, stack y estructura del monorepo |
| Arquitectura | Capas, CQRS, event sourcing, flujo escritura → lectura y tiempo real |
| API | Dominio, workflow de tickets, eventos, GraphQL y REST (OpenAPI) |
| Cliente web | Stores con eventos, GraphQL y @pi/ui |
| Autenticación | Tokens de Pireon, login en el navegador y webhooks |
| Desarrollo | Comandos, tests, cómo añadir una funcionalidad y problemas conocidos |
| Despliegue | Docker, variables de entorno y escalado |
| Decisiones | Por qué está hecho así |
Cada librería de libs/api/* y libs/web/* tiene su propio README.md.
Estructura
apps/api apps/web
libs/api/{shared,identity,tracker}/{domain,application,infrastructure,presenters}
libs/web/{shared,identity,tracker}/{domain,application,infrastructure,presenters} (+ web/shared/ui)
docs/
npx nx run-many -t lint test build # todo
npx nx e2e api # flujo completo contra Docker
npx nx graph # dependencias entre proyectos
Description
Languages
TypeScript
94.1%
SCSS
3.8%
JavaScript
1.7%
Dockerfile
0.2%
HTML
0.2%