Skip to Content
chalvien 1.0 is released
src ├── app/ # Next.js routing layer │ ├── (auth) │ │ ├── login │ │ │ ├── page.tsx │ │ │ └── _components │ │ └── register │ │ └── page.tsx │ │ │ ├── (dashboard) │ │ ├── layout.tsx │ │ ├── inspections │ │ │ ├── page.tsx │ │ │ └── new │ │ │ └── page.tsx │ │ │ │ │ ├── vessels │ │ │ └── page.tsx │ │ │ │ │ └── reports │ │ └── page.tsx │ │ │ ├── api # Optional route handlers │ │ │ ├── layout.tsx │ └── page.tsx ├── features/ # Domain modules │ ├── auth │ │ ├── components │ │ ├── actions │ │ ├── services │ │ └── types.ts │ │ │ ├── inspections │ │ ├── components │ │ ├── actions │ │ ├── services │ │ └── types.ts │ │ │ ├── vessels │ │ ├── components │ │ ├── actions │ │ ├── services │ │ └── types.ts │ │ │ └── questionnaires │ ├── components │ ├── actions │ ├── services │ └── types.ts ├── components/ # Design system │ ├── ui │ └── common ├── hooks ├── lib # infrastructure │ ├── prisma.ts │ ├── db.ts │ └── auth.ts ├── types # global shared types └── config └── constants.ts

2. Architectural Philosophy

1️ App Router = navigation layer

app/

Handles:

  • routing
  • layouts
  • page composition

Example:

app/(dashboard)/inspections/page.tsx

Just renders UI and calls feature logic.

2 Features = business logic

features/inspections

Contains:

components actions services types

Example:

features/inspections/actions/createInspection.ts

Server Action example:

"use server" import { prisma } from "@/lib/prisma" export async function createInspection(data) { return prisma.inspection.create({ data }) }

3 Services = domain logic

Example:

features/inspections/services/inspectionService.ts
import { prisma } from "@/lib/prisma" export async function getInspections() { return prisma.inspection.findMany() }

4 Components

Reusable UI specific to the feature.

features/inspections/components/InspectionTable.tsx

5 Shared UI

components/ui

Design system components:

Button Input Modal Badge Table

3. Example Flow

User opens:

/inspections

Route:

app/(dashboard)/inspections/page.tsx

Page calls:

features/inspections/services/getInspections()

UI renders:

features/inspections/components/InspectionTable

4. Why this works

Your typical apps involve:

  • inspections
  • vessels
  • questionnaires
  • reports
  • users

Each becomes a feature module.

Example:

features/ vessels/ inspections/ questionnaires/ reports/ users/

This avoids huge messy folders like:

lib/ services/ utils/

5. Works perfectly with Prisma

Example infrastructure layer:

lib/prisma.ts
import { PrismaClient } from "@prisma/client" export const prisma = new PrismaClient()

6. Optional: API vs Server Actions

Modern Next.js apps increasingly use:

Server Actions

instead of

API routes

Example:

features/inspections/actions/createInspection.ts

Called directly from a form.

7. Real Example for Inspection App

features/ vessels/ inspections/ questionnaires/ responses/ reports/ users/

This matches exactly your vetting / questionnaire architecture.

Result:

  • scalable
  • domain-oriented
  • easy to maintain
  • excellent with Prisma