A Next.js app for exporting legacy deni-ai chat data per user.
After signing in, users can generate and download message.json in the browser.
- Single-page flow built with the Next.js App Router
- Authentication powered by
better-auth - Email and password sign-in support
- Google and GitHub OAuth support
- Reads legacy chat data from PostgreSQL
- Returns exported JSON through an API endpoint
- The user signs in
- The app verifies the session
GET /api/migration/exportis called- The app loads that user's
chat_sessions - The result is downloaded as
message.json
- Next.js 16
- React 19
- TypeScript
- better-auth
- PostgreSQL (
pg) - Tailwind CSS 4
Set the following values in .env:
DATABASE_URL=
MASTER_DATABASE_URL=
BETTER_AUTH_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=Notes:
DATABASE_URLis used for the auth databaseMASTER_DATABASE_URLis used for legacy chat reads- If
MASTER_DATABASE_URLis omitted,DATABASE_URLis used instead - OAuth provider variables are optional if you do not use OAuth
The app fetches data by authenticated user ID from the following table:
chat_sessions
Expected columns:
iduser_idtitlecreated_atupdated_atmessages
bun installbun devOpen http://localhost:3000 in your browser.
bun dev
bun run build
bun start
bun run lint
bun run lint:fix
bun run format
bun run format:checkReturns the signed-in user's legacy chats as JSON.
If the request is unauthenticated, the endpoint returns 401 Unauthorized.
Response headers:
Content-Type: application/jsonContent-Disposition: attachment; filename="message.json"
Output format:
{
"format": "app-message-export",
"version": 1,
"exportedAt": "2026-03-20T00:00:00.000Z",
"source": {
"app": "deni-ai",
"channel": "master"
},
"chats": []
}- Email / Password
- Google OAuth
- GitHub OAuth
OAuth providers are enabled only when the corresponding environment variables are set.
OAuth sign-up is disabled, so only existing users can sign in.
- Export is limited to data associated with the current
session.user.id user_idmust match UUID format- The exported file name is always
message.json next.config.tscurrently enablestypescript.ignoreBuildErrors
src/app/page.tsxsrc/app/api/migration/export/route.tssrc/app/api/auth/[...all]/route.tssrc/lib/auth.tssrc/lib/db.tssrc/lib/migration.tssrc/lib/types.ts