Imported from josednl/messaging-app (
.agents/AGENTS.md). Install upstream withnpx skills add josednl/messaging-app --skill .agents. Copyright stays with the author.
messaging-app
Project Overview
A full-stack messaging application where users can authenticate, customize their profiles, and exchange private messages with other users. The project focuses on backend architecture, database modeling, authentication, and RESTful communication.
Tech Stack
- Monorepo: pnpm Workspaces
- Backend: Node.js
- Web Framework: Express
- Language: TypeScript
- Frontend: React + Vite
- Styling: Tailwind CSS
- Realtime: Socket.IO
- Unit Testing: Vitest
- Authentication: JWT
- Password Hashing: node:crypto scrypt
- Package Manager: pnpm
- Database: PostgreSQL
- ORM: Prisma
Code Style
- Use ES modules (import/export), not CommonJS.
- Subpath imports: For cross-module access. Keep relative imports for within-module references.
- Naming: PascalCase for classes, components and types. camelCase for variables and functions. UPPER_SNAKE_CASE for constants.
- Prefer explicit types over
any. - Favor composition over inheritance.
Technical Constraints
- Keep TypeScript strict mode enabled.
- Use Prisma for all database access.
- Keep frontend and backend responsibilities clearly separated.
- Do not introduce unnecessary abstractions.
Development Workflow
- Always type check before considering a task complete.
- Format code before committing.
- Verification: Before finalizing changes, run:
pnpm run typecheckandpnpm run test. Add tests for meaningful behavior changes or important logic. Do not add tests solely for coverage or to verify trivial implementation details. - Before modifying any files:
- Check the current branch.
- If the current branch is
main, create and switch to a new feature branch. - Never commit directly to
main. - Continue working only after switching to a non-
mainbranch.
Dev Environment Tips
- PowerShell: Do not use
&&since it is unsupported in older PowerShell versions. Instead use:command1; if ($?) { command2 }.
Database
- Use Prisma migrations for every schema change.
- Never edit existing migrations.
- Prefer normalized relational models.
- Use foreign keys and proper indexes where appropriate.
Architecture
- Keep business logic out of Express route handlers.
- Use controllers only for HTTP concerns.
- Encapsulate database access in services or repositories.
- Keep validation separate from business logic.
- Prefer small, focused modules.
Commits
- Use atomic commits.
- Follow Conventional Commits: type(scope): description
- Commit messages must be written in English.
- Ensure tests and type checking pass before committing.
Monorepo
- Use pnpm workspaces.
- Shared code belongs in packages/shared.
- Never duplicate shared types between client and server.
- Keep dependencies isolated to the package that needs them.
Testing
- Co-locate unit tests with implementation files.
- Keep integration tests under a dedicated directory.
- Test business logic before HTTP endpoints whenever possible.
General
Ponytail Mindset (Lazy Senior Developer)
Apply the KISS principle and the Reflex Ladder for every implementation:
- YAGNI — Don't build features that are not currently needed.
- Platform First — Prefer native HTML, CSS, JavaScript, Node.js and browser APIs.
- Existing Dependency — Reuse packages already installed before adding new ones.
- Minimum Code — Solve the problem with the smallest maintainable solution.
Best Code is No Code
Every dependency, abstraction and line of code has a maintenance cost.
Avoid:
- premature optimization
- unnecessary design patterns
- speculative abstractions
Language
- All code, comments and documentation must be written in English.
Critical Thinking
Do not blindly implement requests.
Before adding new code, ask:
- Can this be solved with native browser or Node.js features?
- Can an existing dependency already solve it?
- Is this abstraction actually reducing complexity?
- Is there a simpler implementation?
When choosing a simpler solution, briefly explain why it improves maintainability.
Non-Negotiable Decisions
- PostgreSQL is the database.
- Prisma is the ORM.
- TypeScript remains in strict mode.
- Authentication must be secure.
- Passwords must be hashed using node:crypto scrypt.
- Import shared dependencies from
@messaging-app/sharedrather than duplicating them in individual packages. - Do not introduce Redux or other global state libraries unless they solve a demonstrated need.
- Keep the project educational and understandable.
Security
- Never store passwords in plain text.
- Hash passwords with node:crypto scrypt.
- Validate every user input.
- Authorize every protected route.
- Prevent users from accessing conversations they do not belong to.
- Never trust client-side validation.
- Use Prisma's parameterized queries exclusively.
- Authenticate Socket.IO connections.
- Never trust Socket.IO payloads.
- Validate every incoming event.
- Verify conversation membership before broadcasting messages.
Roadmap
Foundation
- Monorepo setup (pnpm workspaces)
- Shared package
Backend
- Database schema (Prisma)
- Authentication
- User profiles
- Conversations
- Messages
- File attachments
- Avatars (user & group)
- Guest mode (ephemeral accounts, wiped on logout)
Frontend
- Authentication UI
- Dashboard layout
- Conversations list
- Chat interface
- Unread message counts
- Preferences (theme, font size, locale)
- Internationalization (ES/EN)
Realtime
- Socket.IO integration
- Realtime messaging
- Typing indicators
- Online presence
- Read receipts
Evolution Notes
Monorepo
- Decision: Build the project as a pnpm workspace monorepo.
- Reason: Learn modern full-stack project organization and enable shared code between frontend and backend.
- Implication: Shared types and validation schemas live in packages/shared.
Modular Clean Architecture (DDD + Ports & Adapters)
- Decision: Adopt a modular Clean Architecture (DDD / Hexagonal hybrid) where feature modules are grouped by business capability rather than technical layering.
- Reason: Grouping code by feature module (e.g.,
users/) rather than technical layers (e.g., having a global/controllersor/modelsdirectory) increases cohesion and maintainability. Inward-pointing dependencies ensure the core domain logic is protected from database and web framework details. - Implication: Each feature follows a strict four-layer folder layout:
domain/(pure types and repository ports/interfaces),application/(use-case services),infrastructure/(adapters like Prisma repositories), andpresentation/(Express routes/controllers). A module's public contract is strictly exposed via itsindex.tsbarrel file.