- Confirm auth provider stack: Better Auth + Drizzle adapter, magic-link login for all users, multi-session enabled, no Keycloak/NextAuth.
- Confirm tRPC remains the only backend API surface.
- Confirm React Admin is only under
(admin). - Ensure local development runs (
yarn install,yarn dev). - Ensure database is up-to-date (
yarn db:generate/yarn db:migrate).
- Install Better Auth packages.
- Add env vars:
BETTER_AUTH_SECRET,BETTER_AUTH_URL. - Align session lifetime to ~30 minutes (
expiresIn/updateAge), matching AGENTS.md. - Use Drizzle adapter (no Prisma) and keep config in
src/server/auth/better-auth.ts. - Expose helpers for server/client usage.
- Update
src/server/api/trpc.tsto use Better Auth context. - Migrate server modules importing
authto Better Auth. - Verify admin layout guard: unauthenticated →
/login, non-admin →/, admins allowed.
- Expand
src/server/application-normalizer.tsto map allApplicationData/ApplicationMetafields to/from columns and relation tables (phones, documents, educations, consents, status history). - Remove/avoid legacy JSON fallbacks in
applicationtable or keep them strictly derived through the normalizer; update migrations accordingly. - Introduce
applicationService+applicationRepository(or similar) so tRPC routers stay thin and business rules (status guards, mapping) live in the domain layer. - Centralize date coercion/validation helpers used by applicant/admin flows to keep DRY.
- Add Better Auth catch-all API route
/api/auth/[...all]. - Update
/loginto use Better Auth magic-link flow. - Implement logout via Better Auth client.
- Add
auth.meendpoint for React Admin. - Manually test anonymous/public, login, admin access, logout.
- Remove
next-authimports/config files. - Drop NextAuth deps from
package.json. - Remove unused auth env vars.
- Run lint/typecheck to ensure no references remain.
- Create RA shell (
src/admin/admin-app.tsx) and mount under(admin)/applications. - Implement a basic RA layout that matches existing admin styling.
- Create
src/admin/dataProvider/trpc-data-provider.tsand wire totrpcClient. - Implement full RA interface:
getListwith filters/sort/pagination,getOne,create,update,delete,updateMany,deleteMany,getMany,getManyReference. - Map RA params to dedicated tRPC list endpoints (no hardcoded groupBy) and return
{ data, total }. - Add error handling/logging, especially for UNAUTHORIZED.
- Add small tests for mapping logic (optional).
- Implement Better Auth–backed
adminAuthProviderwith magic-link login and logout. - Ensure
checkAuthrejects non-admins and redirects to login. - Expose identity/permissions for role-based UI.
- Add applications resource with list/show.
- Add edit/create once mutations exist.
- Align resource components with camelCase identifiers per AGENTS.md.
- Port filters/search/pagination/grouping (status/email/name) from legacy admin into RA list views.
- Add sidebar for grouping and batch actions; wire RA bulk actions to tRPC mutations.
- Reuse status mapping and document review flows in RA show/edit views.
- Port admin single-application UI into RA components.
- Add standardized list endpoint returning
{ data, total }with filters/sort/page for RA. - Ensure create/update/delete/bulk mutations exist and enforce ADMIN role.
- Optimize queries (indexes on email/status/createdAt) and avoid N+1 when loading relations.
- Inventory and replace Formik in
single-apply,document-comment,search-field, and input components with controlled orreact-hook-form+ Zod. - Keep nuqs step handling intact; ensure program step remains non-blocking.
- Preserve dynamic fields (phones, documents, educations) with new form approach.
- Remove
formikandzod-formik-adapterusages and packages. - Delete Formik-specific helpers/components.
- Run lint/typecheck to confirm removal.
- Integrate new RA UI with site navigation (admin link for ADMIN users).
- Verify applicant flows (
/apply,/apply/:id,/apply/success,/closed). - Ensure auth redirects/guards behave correctly across routes.
- Run
yarn check,yarn lint,yarn typecheckafter major changes. - Add/adjust tests for tRPC application router and RA dataProvider (if harness present).
- Manual QA: admin login/manage/logout; non-admin rejection; anonymous public access only.
- Confirm admin list performance with pagination and sorting.
- Remove dead legacy admin components once RA is complete.
- Update README with auth/admin stacks and migration guidance.
- Optionally add docs describing RA architecture and tRPC mappings.
- Perform dependency audit for unused packages.