Imported from Amrod92/Waza (
AGENTS.md). Install upstream withnpx skills add Amrod92/Waza. Copyright stays with the author.
AGENTS.md
Purpose
This repository is a project matching product for people who want to find someone to work with.
Current product intent:
- One side publishes projects that need collaborators.
- The other side advertises individual profiles looking for the right project.
- Technical and non-technical users should both feel welcome.
- The app should be agnostic: shops, startups, local ideas, personal projects, creative work, research, and similar projects are all valid.
Important caveat:
- The product language should be project / collaborator oriented.
- The physical schema still uses technical table names like
Project,DevelopmentTool, andCommunication. - Do not assume the database vocabulary matches the UI vocabulary.
Stack
- Next.js
16.2.3 - React
19.2.5 - App Router for UI routes
- Pages Router kept for API routes under
pages/api - Better Auth with Google OAuth
- Supabase as the primary datastore
- TanStack Query for client data fetching
- Tailwind CSS v4
- Local shadcn-style UI primitives under
components/UI
Commands
- Dev server:
npm run dev - Lint:
npm run lint - Build:
npm run build - Start production build:
npm run start - Better Auth schema migration:
npm run auth:migrate - Data migration helper:
npm run migrate:data
Notes:
npm run buildusesnext build --webpack.- This is intentional. Turbopack was previously problematic on this codebase.
Dev Server Notes
next.config.jsincludes:allowedDevOrigins: ['192.168.0.55']
- If dev-origin behavior changes, restart the dev server after editing
next.config.js.
Route Architecture
App Router UI
Main UI routes live under app/:
/->app/page.jsx/about->app/about/page.jsx/privacy->app/privacy/page.jsx/auth/signin->app/auth/signin/page.jsx/dashboard->app/dashboard/page.jsx/projects->app/projects/page.jsx/projects/[id]->app/projects/[id]/page.jsx/projects/create-project->app/projects/create-project/page.jsx/projects/update/[id]->app/projects/update/[id]/page.jsx/collaborators->app/collaborators/page.jsx/settings->app/settings/page.jsx/user/[id]->app/user/[id]/page.jsx
API Routes
UI auth endpoint:
app/api/better-auth/[...all]/route.js
Pages Router API routes remain under pages/api/.
Key endpoints:
pages/api/project/[id].jspages/api/project/createProject.jspages/api/project/delete/[id].jspages/api/project/getAllProjects.jspages/api/project/getProjectsByEmail.jspages/api/project/update/[id].jspages/api/project/update/putUserProject.jspages/api/search/[slug].jspages/api/user/[id].jspages/api/user/connect/[id].jspages/api/user/delete/[id].jspages/api/user/getAllUsers.jspages/api/user/getUserInformation.jspages/api/user/putUserSettings.js
Important product route note:
app/projects/[id]/page.jsxno longer uses Giscus / GitHub comments- project detail pages now use native product actions and guidance instead of public discussion threads
Auth
Shared auth files:
lib/better-auth.jslib/better-auth-client.jslib/better-auth-server.js
Better Auth route:
app/api/better-auth/[...all]/route.js
Current auth behavior:
- Better Auth handles Google OAuth plus session management.
- Better Auth stores auth records in lowercase tables:
usersessionaccountverification
- The app still uses its own Supabase tables like
UserandProject. lib/better-auth.jsuses Better AuthdatabaseHooks.user.create/updateto sync auth users into the app-levelUsertable.lib/better-auth.jsalso exportsdeleteBetterAuthUserByEmail(email)for full account deletion.lib/better-auth-server.jsprovidesgetBetterAuthSession(req, { syncAppUser: true })for Pages API routes.- Use
syncAppUser: trueon authenticated API routes when the app-levelUserrow must exist.
Client auth usage:
betterAuthClient.useSession()for client session statebetterAuthClient.signIn.social({ provider: 'google', callbackURL })for sign-inbetterAuthClient.signOut()for sign-out
Important origin requirements:
BETTER_AUTH_URLmust exactly match the origin used in the browser in local dev.- Do not mix
localhostand192.168.0.55inside the same auth flow. lib/better-auth.jsexplicitly trusts:BETTER_AUTH_URLNEXT_PUBLIC_APP_URLhttp://localhost:3000http://127.0.0.1:3000http://192.168.0.55:3000
Google OAuth callback URL must match the active origin:
http://localhost:3000/api/better-auth/callback/google- or
http://192.168.0.55:3000/api/better-auth/callback/google
App-level providers:
app/providers.jsx
Protected app screens still use a client-side auth guard:
components/UI/auth-guard.jsx
This is pragmatic, not final architecture. If stricter protection is needed later, move more checks server-side.
Environment Notes
Expected local environment variables:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYSUPABASE_SERVICE_ROLE_KEYSUPABASE_DB_URLBETTER_AUTH_SECRETBETTER_AUTH_URLBETTER_AUTH_DATABASE_URLNEXT_PUBLIC_APP_URLGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET
Important distinctions:
SUPABASE_SERVICE_ROLE_KEYis required forutils/supabase-admin.jsNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYis for client Supabase usageBETTER_AUTH_DATABASE_URLorSUPABASE_DB_URLis the Postgres connection string for Better AuthBETTER_AUTH_URLandNEXT_PUBLIC_APP_URLmust match the real dev origin exactly
Common setup-sensitive failures:
- If
SUPABASE_SERVICE_ROLE_KEYis missing, server-side Supabase access fails even if Better Auth works. - If Supabase only has Better Auth tables and not the app tables from
supabase/schema.sql, profile/project APIs fail because tables likeUserandProjectdo not exist. - If Better Auth works but the app-level
Userrow is missing, some profile/settings routes can returnnulluntil the lazy sync path runs. - If only the app
Userrow is deleted without deleting Better Auth records, the user can be recreated later by auth sync. The current delete-account flow now deletes both.
UI System
Prefer local UI primitives in components/UI where possible:
button.jsxcard.jsxinput.jsxtextarea.jsxdialog.jsxdropdown-menu.jsxselect.jsxbadge.jsxavatar.jsxprofile-avatar.jsx
The project does not use the shadcn CLI directly, but follows standard shadcn/ui component patterns and CSS variables.
Visual Direction
The UI direction is modern, high-contrast, and editorial:
- Palette: zinc / black / white
- Typography: Inter for UI text
- Layout: editorial sections, bento-style groupings, generous whitespace
- Branding: Japanese character
技as logo / watermark - Common effects:
glassbg-grid-zinc- mesh / radial gradients
- strong type hierarchy
Product Model Mapping
Current semantic intent
The app speaks in terms like:
- collaborator profile
- project
- project brief
- project stage
- time commitment
- strengths
- industries and interests
- proof and context
Current physical storage reality
Legacy fields still back the product:
Project.title-> project titleProject.description-> project summary / why this mattersProject.tags-> markets / themes / sectorsProject.skills-> ideal collaborator strengthsProject.technology_stack-> helpful backgrounds / domainsProject.development_status-> project stageProject.difficulty_level-> time commitmentProject.team_need-> number of collaborators wanted
Legacy related tables are also repurposed:
Communication-> contact and presence linksDevelopmentTool-> proof, prototype, planning, and work-signal links
Do not rename these lightly without coordinating:
- Supabase schema
- API payloads
- migration scripts
- route UI
Two-Sided Discovery Direction
The current intended product split is:
/projectsfor projects looking for collaborators/collaboratorsfor people advertising themselves as available to work on projects
Current interaction model:
Applyon projectsConnecton people profiles- no GitHub-comment / Giscus discussion layer on project pages
Important nuance:
- Registration alone does not mean a user should appear on
/collaborators. - A user may only want to publish projects.
- People discovery visibility is now explicit opt-in.
Current behavior:
User.show_in_collaborator_feedcontrols whether a person appears on/collaboratorsUser.availabilitystores their declared discovery availability- Default is
false - Settings page exposes this as a
Private/Publicvisibility choice - Settings page also exposes availability values such as
exploring,part_time, andfull_time listUsers()only returns users with:show_in_collaborator_feed === true- and enough profile signal to be meaningful
- Profile cards now enrich user data with:
projectCountconnectionCountsignalRatingisConnectedToViewer
Schema note:
supabase/schema.sqlnow includesshow_in_collaborator_feed boolean not null default falseonUsersupabase/schema.sqlnow includesavailability text not null default 'not_specified'onUsersupabase/schema.sqlnow includes aConnectiontable for user-to-user connections- Existing Supabase projects may need the manual SQL:
alter table public."User" add column if not exists show_in_collaborator_feed boolean not null default false;alter table public."User" add column if not exists availability text not null default 'not_specified';- create
public."Connection"if the project predates connections
API Payloads
Project API routes should use the current project/collaborator payload names only.
Relevant files:
pages/api/project/createProject.jspages/api/project/update/putUserProject.js
Do not add old vocabulary aliases unless a migration requires it explicitly.
Data Layer
Primary data helper:
utils/supabase-db.js
Important exported functions include:
syncUserFromAuthgetUserByEmailgetUserByIdlistUserslistProjectsgetProjectByIdgetProjectsByUserEmailsearchProjectscreateProjectForUsercreateConnectionBetweenUsersupdateProjectByIdupdateUserSettingsByEmaildeleteProjectByIddeleteUserById
Notes:
- Function names still use
Projectterminology. This is technical debt, but still accurate for the current schema. User.nameis currently treated as a full-name field in the UI.- There is no separate surname / last-name column.
User.hobbiescurrently backs “passions, industries, and interests” in the UI.User.availabilitystores people-discovery availability, not project-level commitment.
Schema Status
Runtime storage uses Supabase.
Supabase has two distinct groups of tables:
-
Better Auth tables:
usersessionaccountverification
-
App tables from
supabase/schema.sql:UserUserSocialProfileProjectDevelopmentToolCommunicationConnection
Both groups are required. Creating only the Better Auth tables is not enough for the app to function.
Migration-related work currently lives in:
scripts/migrate-postgres-to-supabase.mjs
If you perform a real backend model rename, update:
- Supabase SQL
- API handlers
utils/supabase-db.js- migration scripts
- docs in
README.md
Error Handling
The application generally uses user-friendly API/UI messages while logging detailed errors server-side.
Examples:
- API routes often return generic messages like
Unable to load projects at this time - UI surfaces often use error cards with retry actions
- environment/configuration problems log more detail on the server than the client sees
Known Architectural Debt
These are still valid follow-up areas:
- Some backend table names are still technical implementation names.
- Some API route names still reflect the older product model.
- Search/filtering is still listing-metadata-driven, not real fit matching.
- App Router auth protection is still mostly client-side.
- The settings/profile flows still contain substantial repetitive form logic.
- Project applications are still lightweight CTA-driven, not a full in-app application system.
- Profile credibility is currently a computed signal score, not a true review or endorsement system.
@giscus/reactmay still remain in dependencies even though the project page discussion block has been removed.
Files Worth Reading First
If you are picking up work, read these first:
package.jsonnext.config.jsapp/layout.jsxapp/providers.jsxlib/better-auth.jslib/better-auth-client.jslib/better-auth-server.jsutils/supabase-db.jsapp/page.jsxapp/projects/page.jsxapp/collaborators/page.jsxapp/projects/[id]/page.jsxapp/projects/create-project/page.jsxapp/settings/page.jsxapp/user/[id]/page.jsxcomponents/NavbarUI/Navbar.jsxcomponents/ProjectsCard.jsxcomponents/CollaboratorCard.jsx
Safety Notes
- The worktree may already be dirty. Do not revert unrelated user changes.
- Prefer incremental refactors over large schema renames unless you are explicitly completing the backend migration too.
- If you add new matching fields, decide whether they are:
- UI aliases mapped to existing columns, or
- real storage fields requiring schema changes
Be explicit about that choice before implementing.