next and nest

This commit is contained in:
Emmanuel Rojas committed 2026-09-22 14:08:17 -05:00
1 parent 55f69fbbb4
commit 90125aede9
30 files changed
+3754 -344

No files matched your search

+8 -5
View File
@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies # dependencies
/node_modules node_modules
/.pnp /.pnp
.pnp.* .pnp.*
.yarn/* .yarn/*
@@ -11,14 +11,17 @@
!.yarn/versions !.yarn/versions
# testing # testing
/coverage coverage
# next.js # next.js
/.next/ .next/
/out/ out/
# nest.js
dist/
# production # production
/build build
# misc # misc
.DS_Store .DS_Store
+36 -21
View File
@@ -1,36 +1,51 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). Monorepo con [npm workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces) que combina un backend [NestJS](https://nestjs.com) y un frontend [Next.js](https://nextjs.org).
## Getting Started ## Estructura
First, run the development server: ```
apps/
api/ NestJS — servidor HTTP real del proyecto
web/ Next.js (App Router) — frontend
```
En **desarrollo y producción se levanta un único servidor**: `apps/api` (Nest) arranca, monta sus controladores bajo el prefijo `/api`, y luego delega cualquier otra ruta al request handler programático de Next.js (`apps/web`). No hay dos puertos ni dos procesos — Nest "sirve" a Next.
Ver `apps/api/src/main.ts` para el detalle de la integración.
## Empezar
Instala las dependencias una sola vez desde la raíz (los workspaces se resuelven juntos):
```bash
npm install
```
### Desarrollo
```bash ```bash
npm run dev npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
``` ```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. Levanta Nest en modo watch (`nest start --watch`), que a su vez prepara Next en modo desarrollo. Todo queda disponible en [http://localhost:3000](http://localhost:3000) (API bajo `/api/*`).
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. ### Build y producción
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ```bash
npm run build # compila apps/web (next build) y luego apps/api (nest build)
npm run start # node apps/api/dist/main.js
```
## Learn More ### Solo frontend (aislado)
To learn more about Next.js, take a look at the following resources: Si necesitas iterar en `apps/web` sin levantar Nest:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. ```bash
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. npm run dev --workspace=@pdv/web
```
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! Ten en cuenta que en ese modo las rutas `/api/*` de Nest no estarán disponibles.
## Deploy on Vercel ## Notas de configuración
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - El custom server de Next (`next({ dev, dir })`) no es compatible con `output: "standalone"` — no lo actives en `apps/web/next.config.ts` mientras Nest siga sirviendo el build.
- `apps/api` usa TypeScript 6.x (distinto de `apps/web`, que usa TypeScript 5.x) porque `@nestjs/cli`/`nest build` aún no soportan la API programática del compilador de TypeScript 7.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
+32
View File
@@ -0,0 +1,32 @@
import eslint from '@eslint/js';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default tseslint.config(
{
ignores: ['dist/**'],
},
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
eslintPluginPrettierRecommended,
{
languageOptions: {
globals: {
...globals.node,
},
sourceType: 'commonjs',
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/no-unsafe-argument': 'warn',
},
},
);
+8
View File
@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}
+35
View File
@@ -0,0 +1,35 @@
{
"name": "@pdv/api",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:prod": "node dist/main.js",
"lint": "eslint \"{src,test}/**/*.ts\" --fix"
},
"dependencies": {
"@nestjs/common": "^12.0.3",
"@nestjs/core": "^12.0.3",
"@nestjs/platform-express": "^12.0.3",
"next": "^16.3.5",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2"
},
"devDependencies": {
"@eslint/js": "^9.39.5",
"@nestjs/cli": "^12.0.3",
"@nestjs/schematics": "^12.0.0",
"@nestjs/testing": "^12.0.3",
"@types/express": "^5.0.6",
"@types/node": "^20.19.43",
"eslint": "^9.39.5",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.6",
"globals": "^14.0.0",
"prettier": "^3.9.8",
"typescript": "^6.0.3",
"typescript-eslint": "^8.70.0"
}
}
+12
View File
@@ -0,0 +1,12 @@
import { Controller, Get } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get("health")
getHealth() {
return this.appService.getHealth();
}
}
+10
View File
@@ -0,0 +1,10 @@
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
+8
View File
@@ -0,0 +1,8 @@
import { Injectable } from "@nestjs/common";
@Injectable()
export class AppService {
getHealth() {
return { status: "ok" };
}
}
+35
View File
@@ -0,0 +1,35 @@
import "reflect-metadata";
import path from "node:path";
import { NestFactory } from "@nestjs/core";
import type { NestExpressApplication } from "@nestjs/platform-express";
import next from "next";
import { AppModule } from "./app.module";
async function bootstrap() {
const dev = process.env.NODE_ENV !== "production";
const port = Number(process.env.PORT ?? 3000);
// apps/api siempre corre compilado desde dist/, por lo que apps/web
// queda dos niveles arriba tanto en desarrollo como en producción.
const nextApp = next({ dev, dir: path.join(__dirname, "../../web") });
const handleNextRequest = nextApp.getRequestHandler();
await nextApp.prepare();
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.setGlobalPrefix("api");
// Se inicializa antes de registrar el catch-all para que las rutas de
// Nest queden montadas primero y Next solo reciba lo que Nest no maneja.
await app.init();
app
.getHttpAdapter()
.getInstance()
.all(/.*/, (req, res) => handleNextRequest(req, res));
await app.listen(port);
console.log(
`> Servidor listo en http://localhost:${port} (${dev ? "development" : "production"})`,
);
}
void bootstrap();
+4
View File
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ES2023",
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"noFallthroughCasesInSwitch": true
}
}
File renamed without changes.
File renamed without changes.
+28
View File
@@ -0,0 +1,28 @@
{
"name": "@pdv/web",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"@heroui/react": "^3.2.6",
"framer-motion": "^13.4.0",
"next": "16.3.5",
"react": "19.2.8",
"react-dom": "19.2.8"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.3.5",
"tailwindcss": "^4",
"typescript": "^5"
}
}
File renamed without changes.
@@ -1,4 +1,4 @@
@import "tailwindcss"; @import "@heroui/react/styles";
:root { :root {
--background: #ffffff; --background: #ffffff;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3508 -297
View File
File diff suppressed because it is too large. Load diff
+8 -20
View File
@@ -1,26 +1,14 @@
{ {
"name": "pdv-frontend", "name": "pdv",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"workspaces": [
"apps/*"
],
"scripts": { "scripts": {
"dev": "next dev", "dev": "npm run start:dev --workspace=@pdv/api",
"build": "next build", "build": "npm run build --workspace=@pdv/web && npm run build --workspace=@pdv/api",
"start": "next start", "start": "npm run start:prod --workspace=@pdv/api",
"lint": "eslint" "lint": "npm run lint --workspace=@pdv/web && npm run lint --workspace=@pdv/api"
},
"dependencies": {
"next": "16.3.5",
"react": "19.2.8",
"react-dom": "19.2.8"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.3.5",
"tailwindcss": "^4",
"typescript": "^5"
} }
} }