Julien Calixte 9ded10f68e feat(napta): client-credentials auth + real project listing
Napta uses Auth0 M2M, not a static token: exchange client_id/secret for a cached
JWT, then list non-archived projects via JSON:API (include client name). Falls back
to fixtures when NAPTA_CLIENT_ID/SECRET are unset. Member resolution still stubbed.
2026-06-26 16:16:06 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00
2026-06-26 15:26:20 +01:00

photofetch

Deployed at https://photofetch.apoena.dev

Pick a Napta project and get a grid of the people staffed on it — each with their Slack profile picture, first name, last name, and role. People are matched between Napta and Slack by email.

Architecture

  • frontend (repo root) — Vite + Vue 3 + TypeScript + Tailwind v4 + DaisyUI SPA.
  • backend/ — TypeScript/Node API (Hono) that proxies Napta + Slack so their tokens never reach the browser. Runs .ts directly on Node 24 (no build step); SQLite via the built-in node:sqlite module (avatar cache at data/app.db). Serves demo fixtures until live credentials are configured.

In production, nginx serves the built SPA and proxies /api to the backend service (see nginx.conf + docker-compose.yml).

Develop

pnpm install
pnpm dev                                  # frontend on :5173 (proxies /api -> :8000)
cd backend && pnpm install && pnpm dev    # API on :8000
# …or run the whole stack in containers (open http://localhost:8080):
docker compose up --build

Deploy gates (run before pushing):

pnpm lint            # oxlint   (pnpm lint:fix to autofix)
pnpm fmt:check       # oxfmt    (pnpm fmt to format)
pnpm build           # vue-tsc + vite build, no warnings
cd backend && pnpm typecheck

Configuration (live data)

Set on the Coolify app (or in backend/.env locally — see backend/.env.example):

Var Purpose
NAPTA_API_TOKEN Napta API token (lists projects + their people)
NAPTA_BASE_URL Napta API base (default https://app.napta.io/api/v1)
SLACK_BOT_TOKEN Slack bot token, scopes users:read + users:read.email

Without both tokens the API serves demo fixtures and the UI shows a "demo data" banner.

Deploy

Pushes to main are picked up by Coolify at https://platform.apoena.dev and deployed to https://photofetch.apoena.dev.

Description
photofetch.apoena.dev
Readme 113 KiB
Languages
TypeScript 62.7%
Vue 30.6%
Dockerfile 2.5%
CSS 1.7%
Shell 1.6%
Other 0.9%