# v2.0 Research: Pitfalls

**Date:** 2026-05-15

## Authentication

- Do not trust OAuth callback parameters without validating state and nonce.
- Do not use provider access tokens as Xtablo sessions. They are not the local session authority.
- Do not link accounts by unverified email.
- Apple may only provide some profile fields on first authorization; persist what is needed immediately.
- Apple client secret generation is easy to get wrong: use ES256, correct `kid`, `iss`, `aud`, `sub`, and expiration.
- Provider subject, not email, is the stable external identity key.

## Chat

- Do not treat the in-process real-time hub as durable storage. Every message must commit to Postgres first.
- SSE connections need keep-alive comments/events to avoid idle timeouts.
- Browser/domain connection limits matter for SSE over HTTP/1.1; keep one stream per tablo view and document the limitation.
- Message POSTs must keep CSRF protection. SSE stream endpoints should be GET-only and authenticated.
- Avoid storing unbounded message bodies; enforce length limits.
- Avoid HTML injection by rendering message bodies through templ escaping, not safe HTML.

## Etapes

- Do not model etapes as recursive tasks unless the product explicitly needs nested hierarchy later.
- Adding `tasks.etape_id` should not break existing kanban ordering.
- Deleting an etape should not delete its tasks unless the user explicitly confirms that behavior; default to unassigning tasks.

## Events / Planning

- Store timestamps as `timestamptz`.
- Require `ends_at` to be null or after `starts_at`.
- Decide the first timezone behavior explicitly. For v2, storing absolute times and displaying in the user's browser/local preference is enough.
- Planning should not leak events from tablos the user cannot access.

## Deployment

- WebSockets may require reverse-proxy upgrade config. SSE usually works through normal HTTP but still needs buffering disabled if the proxy buffers streams.
- If using Caddy, verify streaming behavior during human UAT.
