GROWI main application (apps/app) architecture, directory structure, and design patterns. Auto-invoked when working in 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.
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
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
features/{feature-name}/interfaces/server/ (models, routes, services)client/ (components, hooks, states)index.tsserver/app.ts - Express + Next.js initializationpages/_app.page.tsx - Jotai + SWR providerspages/[[...path]]/index.page.tsx - Catch-all route (SSR)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);
});
states/stores-universal/For detailed patterns, see app-specific-patterns skill.
features/features/Legacy directories (components/, server/models/, client/) should be gradually migrated to features/:
features/features/features/{feature-name}/ structure