Commit Graph

60 Commits

Author SHA1 Message Date
240ea9a539 feat(web): team list on the tracking dashboard
"¿Quién está con qué?" only listed people with open tickets. The tracking
page now shows the whole team: every member with their role and open
tickets (0 included), busiest first, plus former members who still have
tickets and the unassigned count. Each person links to the board filtered
by them: the board accepts ?assignee= like ?release=.

Role colours move to ui/copy.ts (shared with the members page). Docs and
Word/PDF updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:14:46 +02:00
6c3550ae9d docs(auth): two Pireon clients, production URLs and sign-in troubleshooting
- Registering clients: the authorization_code client is confidential and needs
  its secret; Pireon shows it once (rotate-secret if lost); containers must be
  recreated to read new environment variables.
- Production URLs (taskstream.pireon.dev, api.taskstream.pireon.dev) and their
  redirect URIs.
- "Si el login falla": each error seen while deploying (not configured,
  unauthorized_client, missing client_secret, invalid_client, redirect URI,
  expired code, wrong credentials, intermittent 404s) with cause and fix.
- READMEs mention both clients; Word/PDF regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:01:33 +02:00
b1002e6599 fix(auth): keep Pireon's OAuth error hint in token errors and logs
Passport answers token failures with a generic `invalid_request` description
and puts the actual cause in `hint` (invalid redirect URI, expired or revoked
code, code issued to another client…). The proxy dropped it, so sign-in
showed only "The request is missing a required parameter…". It is now
appended to the error message and logged with the grant type and client id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:52:16 +02:00
cbaad17fc7 fix(auth): separate Pireon clients for authorization code and password
Pireon OAuth clients allow a single grant type. With one PIREON_CLIENT_ID of
type password, email + password worked but "Sign in with Pireon" failed with
`unauthorized_client`.

- PIREON_CLIENT_ID/SECRET: authorization_code client (Sign in with Pireon,
  Swagger UI). New PIREON_PASSWORD_CLIENT_ID/SECRET: password client, falling
  back to the former so existing setups keep working.
- Refresh tries both clients: a refresh token only works with its issuer.
- PIREON_PASSWORD_GRANT=false now also rejects password grants in the API
  (before it only hid the form).
- /api/auth/config returns clientId: null when there is no authorization_code
  client, and the web hides "Sign in with Pireon".
- docker-compose passes the new variables; docs 05/07, .env.example,
  openapi.json; unit tests for the client selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:41:50 +02:00
7532938b4e fix(docker): reach services by unique aliases, not bare service names
In Dokploy, services with a domain join the shared dokploy-network, where
another project also has an `api`. nginx proxied /api to `api:3000`, so
Docker DNS returned both containers and half of the requests went to the
other app: 404 "Cannot POST /api/auth/token" on sign-in and "sign-in not
configured" when /api/auth/config was answered by it.

Services now get task-stream-* aliases on the project network and nginx and
the API use them (task-stream-api, -postgres, -mongo, -redis). The API's
OPENAPI_FILE is empty in the container; docs 07 explain the aliases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:26:47 +02:00
341241a52f feat(api): REST API with OpenAPI for other apps, behind Pireon OAuth
A REST adapter next to GraphQL (presenters/http) that calls the same
application services, so validation, permissions and domain errors are the
same: projects (members, board, stats, activity), issues (search, workflow,
assignee, release, links, comments, history), comments, releases and users.
Projects and issues can be addressed by id or key (WEB, WEB-12).

- Swagger UI at /api/docs, document at /api/docs-json and apps/api/openapi.json
  (rewritten by `nx serve api`, like schema.gql) for client generation.
- Every route but health/auth/webhook needs a Pireon token: the document
  declares Pireon OAuth2 (authorization code + PKCE, password) through the
  /api/auth/token proxy, and a bearer scheme for apps with their own client.
- configureApp() shares main.ts setup with the e2e, which now also covers REST.
- SWAGGER_ENABLED / OPENAPI_FILE config; docs 03/05 and library READMEs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:26:47 +02:00
b2c9be72c3 chore(docker): publish ports only in development
docker-compose.yml is the production definition (deployed by Dokploy) and no
longer publishes any port: postgres, mongo, redis and the API are reachable
only on the compose network, and the web goes out through the platform's
proxy (domain → service web, port 80). The ports moved to
docker-compose.override.yml, which Compose loads automatically locally and
Dokploy (-f docker-compose.yml) does not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:16:50 +02:00
bf0294a188 fix(docker): read the Nexus token from NEXUS_TOKEN instead of ~/.npmrc
Dokploy builds failed with "failed to stat /root/.npmrc": the compose build
secret pointed at ${HOME}/.npmrc, which only exists on a developer machine.
The token now comes from the NEXUS_TOKEN environment variable (Dokploy's
Environment tab or .env), is written to a temporary npmrc and removed in the
same RUN, so it never lands in an image layer.

Also removes a temporary UI dev-server spec that was committed by mistake,
and documents the variable (.env.example, docs 06/07, Word/PDF export).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:11:01 +02:00
566f415fa7 first commit 2026-10-03 13:40:26 +02:00
732a5b5a16 Initial commit 2026-10-03 13:40:12 +02:00