name: app-architecture description: GROWI main application (apps/app) architecture, directory structure, and design patterns. Auto-invoked when working in apps/app. user-invocable: false
App Architecture (apps/app)
The main GROWI application is a full-stack Next.js application with Express.js backend and MongoDB database.
For technology stack details, see the global tech-stack skill.
Directory Structure
apps/app/src/
├── pages/ # Next.js Pages Router (*.page.tsx)
├── features/ # Feature modules (recommended for new code)
│ └── {feature-name}/
│ ├── index.ts # Public exports
│ ├── interfaces/ # TypeScript types
│ ├── server/ # models/, routes/, services/
│ └── client/ # components/, states/, hooks/
├── server/ # Express server (legacy)
│ ├── models/ # Mongoose models
│ ├── routes/apiv3/ # RESTful API v3
│ └── services/ # Business logic
├── components/ # React components (legacy)
├── states/ # Jotai atoms
└── stores-universal/ # SWR hooks
Feature-Based Architecture
Organize code by business feature rather than by technical layer:
❌ Layer-based (old): ✅ Feature-based (new):
├── models/User.ts ├── features/user/
├── routes/user.ts │ ├── server/models/User.ts
├── components/UserList.tsx │ ├── server/routes/user.ts
│ └── client/components/UserList.tsx
Creating a New Feature
- Create
features/{feature-name}/ - Define interfaces in
interfaces/ - Implement server logic in
server/(models, routes, services) - Implement client logic in
client/(components, hooks, states) - Export public API through
index.ts
Entry Points
- Server:
server/app.ts- Express + Next.js initialization - Client:
pages/_app.page.tsx- Jotai + SWR providers - Wiki Pages:
pages/[[...path]]/index.page.tsx- Catch-all route (SSR)
API Design (RESTful API v3)
Routes in server/routes/apiv3/ with OpenAPI specs:
/**
* @openapi
* /api/v3/pages/{id}:
* get:
* summary: Get page by ID
*/
router.get('/pages/:id', async (req, res) => {
const page = await PageService.findById(req.params.id);
res.json(page);
});
State Management
- Jotai: UI state (modals, forms) in
states/ - SWR: Server data (pages, users) in
stores-universal/
For detailed patterns, see app-specific-patterns skill.
Design Principles
- Feature Isolation: New features self-contained in
features/ - Server-Client Separation: Prevent server code bundled into client
- API-First: Define OpenAPI specs before implementation
- Type-Driven: Define interfaces before implementation
- Progressive Migration: Gradually move legacy code to
features/
Legacy Migration
Legacy directories (components/, server/models/, client/) should be gradually migrated to features/:
- New features →
features/ - Bug fixes → Can stay in legacy
- Refactoring → Move to
features/
Summary
- New features:
features/{feature-name}/structure - Server-client separation: Keep separate
- API-first: OpenAPI specs for API v3
- State: Jotai (UI) + SWR (server data)
- Progressive migration: No rush for stable legacy code