System
apps/system/README.md
apps/01-base-app
Plantilla base para nuevas aplicaciones dentro del monorepo Nidus. Contiene la estructura, configuración y convenciones necesarias para iniciar rápidamente cualquier app del ecosistema.
1. Propósito
01-base-app es la plantilla de referencia para crear nuevas aplicaciones en Nidus. Define:
- Estructura estándar de carpetas y archivos
- Stack tecnológico unificado (Next.js, React, TypeScript, Tailwind v4)
- Integración con paquetes compartidos (
@repo/ui,@repo/hooks,@repo/constants, etc) - Configuración centralizada (ESLint, TypeScript, PostCSS)
- Flujo de desarrollo y deployment usando Firebase App Hosting
2. Stack Tecnológico
| Capa | Tecnología | Versión |
|---|---|---|
| Framework | Next.js (App Router) | 16.1.7 |
| Runtime | Node.js 20+ (compatible con Firebase) | — |
| Lenguaje | TypeScript | 5.9.2 |
| UI/Styling | Tailwind CSS v4 (CSS-first, reactive tokens) | 4.1.9 |
| Componentes | @repo/ui (shadcn/ui + Radix UI) | ws:* |
| Íconos | @repo/icons (Lucide React) | ws:* |
| Hooks Custom | @repo/hooks (useIsMobile, etc) | ws:* |
| Constantes | @repo/constants (colores, logos, configuración) | ws:* |
| Validación | Zod (a través de @repo/schemas) | — |
| Animaciones | Tailwind Animate (tailwindcss-animate) | 1.0.7 |
| Testing | Vitest (setup opcional) | — |
3. Estructura de Carpetas
01-base-app/
├── app/ # Next.js App Router
│ ├── (dev)/ # Grupo de rutas (desarrollo/features)
│ ├── api/ # Rutas API
│ ├── globals.css # Punto de entrada Tailwind v4
│ ├── layout.tsx # Layout raíz (RootLayout)
│ ├── page.tsx # Página home
│ ├── apple-icon.tsx # Apple app icon (favicon)
│ ├── icon.tsx # Favicon/app icon
│ ├── manifest.ts # Web app manifest (PWA)
│ ├── opengraph-image.tsx # OG image para redes sociales
│ └── [dynamic]/ # Rutas dinámicas
├── lib/ # Utilidades y helpers
│ ├── firebaseClient.ts # Instancia Firebase cliente
│ └── [utilidades].ts # Funciones reutilizables
├── constants/ # Constantes locales de la app
│ └── routes.ts # Rutas públicas, privadas, etc.
├── next.config.ts # Configuración Next.js
├── tsconfig.json # Configuración TypeScript (extiende @repo/tsconfig)
├── postcss.config.mjs # Configuración PostCSS (Tailwind)
├── package.json # Dependencias y scripts
├── eslint.config.mjs # ESLint config (extiende @repo/eslint)
├── apphosting.test.yaml # Configuración Firebase App Hosting
└── README.md # Este archivo
4. Configuración de Archivos
4.1 TypeScript (tsconfig.json)
Extiende la configuración base del monorepo con rutas de alias locales:
{
"extends": "@repo/tsconfig/tsconfig.base.json",
"compilerOptions": {
"jsx": "preserve",
"allowJs": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Nota: El alias @/* permite importar desde la raíz de la app:
// ✅ Buen:
import { Button } from '@/components/button';
// ❌ Evitar:
import { Button } from '../../../components/button';
4.2 Next.js (next.config.ts)
Configuración minimal. Extensible según necesidades (imagen optimization, headers, rewrites, etc):
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;
4.3 PostCSS (postcss.config.mjs)
Integración con Tailwind v4:
export default {
plugins: {
tailwindcss: {},
},
};
4.4 ESLint (eslint.config.mjs)
Extiende la configuración base de Rappid Tech:
import { config as baseConfig } from '@repo/eslint/next.config.js';
export default [
...baseConfig,
{
rules: {
// Overrides locales si es necesario
},
},
];
4.5 Tailwind CSS (app/globals.css)
Punto de entrada crítico para estilos Tailwind v4. Orden de imports es fundamental:
@import 'tailwindcss';
@plugin 'tailwindcss-animate';
/* Detecta clases en @repo/ui */
@source '../../../packages/ui/src';
/* Importa tokens semánticos y paleta de diseño */
@import '../../../packages/ui/src/styles/globals.css';
/* Estilos base de la app */
body {
@apply bg-background text-foreground;
}
Variables CSS reactivas disponibles (desde @repo/ui):
/* Colores semánticos */
--color-primary / --color-primary-foreground
--color-secondary / --color-secondary-foreground
--color-accent / --color-accent-foreground
--color-destructive / --color-destructive-foreground
/* Estados */
--color-success / --color-error / --color-warning / --color-info
/* Superficies */
--color-background / --color-surface / --color-card
--color-border / --color-border-strong
/* Texto */
--color-text-primary / --color-text-secondary / --color-text-muted
5. Integración con Paquetes Compartidos
5.1 Componentes UI (@repo/ui)
import { Button, Card, Input } from '@repo/ui/components';
export default function Page() {
return (
<Card>
<h1>Bienvenido a Nidus</h1>
<Button>Comenzar</Button>
</Card>
);
}
5.2 Íconos (@repo/icons)
import { ChevronDown, Settings } from '@repo/icons';
export function Header() {
return (
<button>
<Settings size={20} />
</button>
);
}
5.3 Constantes (@repo/constants)
import {
APP_COLORS,
APP_SEMANTIC_COLORS,
APP_CONFIG_COLORS,
APP_BRAND_COLORS,
} from '@repo/constants';
// Usar en config
export const themeConfig = {
primary: APP_CONFIG_COLORS.brand.primary,
secondary: APP_CONFIG_COLORS.brand.secondary,
};
// Usar en componentes
<div style={{ backgroundColor: APP_BRAND_COLORS.forest['500'] }}>Contenido</div>;
5.4 Hooks Customizados (@repo/hooks)
import { useIsMobile } from '@repo/hooks';
export function ResponsiveComponent() {
const isMobile = useIsMobile();
return isMobile ? <MobileLayout /> : <DesktopLayout />;
}
5.5 Esquemas y Validación (@repo/schemas)
import { z } from 'zod';
import { schemas } from '@repo/schemas';
const formSchema = z.object({
email: schemas.email,
name: schemas.nonEmptyString,
});
5.6 Firebase Adaptadores
Cliente (@repo/firebase-client-adapter)
import { getAuth, getCurrentUser } from '@repo/firebase-client-adapter';
export async function UserProfile() {
const user = await getCurrentUser();
return <p>{user?.email}</p>;
}
Servidor (@repo/firebase-admin-adapter)
Se usa solo en Route Handlers o Server Actions. No incluir en el navegador.
6. Marca y Branding
6.1 Paleta de Colores
Los colores están definidos en @repo/constants/src/colors/app-colors.ts:
// Escalas de color nombradas por marca
export const APP_BRAND_COLORS = {
forest: { 50, 100, 200, ..., 950 }, // Verde Bosque (primario)
sand: { 50, 100, 200, ..., 950 }, // Arena (secundario)
brick: { 50, 100, 200, ..., 950 }, // Naranja Ladrillo (tertiary)
deepBlue: { 50, 100, 200, ..., 950 }, // Azul Intenso (quaternary)
};
// Semánticos para componentes
export const APP_SEMANTIC_COLORS = {
background: '#fdfdf9',
primary: '#587469',
primaryForeground: '#ffffff',
// ... más
};
6.2 Logos y Assets
Los logos están en packages/icons/src/logos/:
import { LogoNidus } from '@repo/icons';
export function Header() {
return <LogoNidus size={40} />;
}
7. Desarrollo
7.1 Instalación y Setup
# Desde la raíz del monorepo
pnpm install
# Verificar tipos
pnpm check-types
# Verificar linting
pnpm lint
7.2 Correr en Desarrollo
# Solo esta app
pnpm dev --filter=01-base-app
# Todo el monorepo
pnpm dev
Corre en http://localhost:3000 (o siguiente puerto disponible).
7.3 Comandos Disponibles
# Desarrollo
pnpm dev --filter=01-base-app
# Build
pnpm build --filter=01-base-app
# Verificación de tipos
pnpm check-types --filter=01-base-app
# Linting
pnpm lint --filter=01-base-app
# Testing (si está configurado)
pnpm test --filter=01-base-app
8. Deployment
8.1 Firebase App Hosting
Esta app se despliega usando Firebase App Hosting desde la rama main automáticamente.
Configuración: apphosting.test.yaml
runtime: nodejs20
build:
commands:
- npm install -g pnpm
- pnpm install
- pnpm build --filter=01-base-app
env:
FIREBASE_CONFIG: '' # Inyectado automáticamente
8.2 Variables de Entorno
Crear un archivo .env.local en la raíz de la app:
NEXT_PUBLIC_FIREBASE_API_KEY=...
NEXT_PUBLIC_FIREBASE_PROJECT_ID=...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=...
# Más vars según necesidad
Las vars con prefijo NEXT_PUBLIC_ están disponibles en el navegador.
8.3 Verificación pre-deploy
# Compilar
pnpm build --filter=01-base-app
# Verificar que inicia
pnpm start --filter=01-base-app
9. Crear una Nueva App Basada en Esta Plantilla
9.1 Opción A: Clonar y adaptar
# 1. Duplicar la carpeta
cp -r apps/01-base-app apps/nueva-app
# 2. Actualizar package.json
{
"name": "nueva-app",
"version": "0.1.0",
"private": true,
# ... mantener el resto igual
}
# 3. Actualizar referencias en next.config.ts, tsconfig.json, etc.
# (Las rutas relativas pueden necesitar ajustes)
# 4. Instalar dependencias
pnpm install
# 5. Correr y testear
pnpm dev --filter=nueva-app
9.2 Opción B: Manual (recomendado)
# 1. Crear carpeta
mkdir apps/nueva-app && cd apps/nueva-app
# 2. Crear package.json mínimo (copiar de 01-base-app)
# 3. Crear estructura:
mkdir -p app/api lib constants
touch next.config.ts tsconfig.json postcss.config.mjs eslint.config.mjs
touch app/{layout.tsx,page.tsx,globals.css,icon.tsx,manifest.ts}
# 4. Copiar archivos de 01-base-app
# 5. Instalar y verificar
pnpm install
pnpm dev --filter=nueva-app
9.3 Checklist para nueva app
-
package.jsoncon nombre único -
tsconfig.jsonextendiendo@repo/tsconfig -
next.config.ts(puede estar vacío) -
postcss.config.mjscon Tailwind -
eslint.config.mjsextendiendo@repo/eslint -
app/layout.tsxcon estructura básica -
app/page.tsxcon contenido inicial -
app/globals.csscon imports de Tailwind - Variables de entorno en
.env.local -
apphosting.test.yamlpara deploy - README.md con documentación específica de la app
- Agregar a
pnpm-workspace.yamlsi es necesario (generalmente automático)
10. Convenciones y Best Practices
10.1 Estructura de Rutas
Usar route groups (grupo) para organizar sin afectar URL:
app/
├── (dev)/ # Features de desarrollo/admin
│ ├── dashboard/
│ └── settings/
├── (public)/ # Páginas públicas
│ ├── home/
│ └── about/
└── (auth)/ # Flujos de auth
├── login/
└── register/
10.2 Componentes
lib/
├── components/
│ ├── ui/ # Primitivos (inputs, buttons reusables)
│ └── features/ # Compuestos (forms, cards complejas)
└── hooks/
10.3 Nombrado de Archivos
- Componentes React:
PascalCase(UserCard.tsx) - Utilidades:
camelCase(getUserData.ts) - Constantes:
UPPER_SNAKE_CASE(API_ENDPOINT) - Tipos/Interfaces:
PascalCase(UserProps,Product)
10.4 Tipos TypeScript
// ✅ Exportar tipos compartidos
export interface UserProfile {
id: string;
email: string;
role: 'admin' | 'user';
}
// ✅ Usar tipos de props explícitos
interface UserCardProps {
user: UserProfile;
onSelect?: (user: UserProfile) => void;
}
export function UserCard({ user, onSelect }: UserCardProps) {
return <div onClick={() => onSelect?.(user)}>{user.email}</div>;
}
11. Troubleshooting
El build falla
# Limpiar node_modules y cache
pnpm clean
pnpm install
# Verificar tipos
pnpm check-types
Tailwind CSS no aplica estilos
- Verificar que
globals.cssesté importado enlayout.tsx - Confirmar
@sourceapunta a@repo/uicorrectamente - Limpiar
.next/:rm -rf .next && pnpm dev
Imports fallando
- Verificar alias
@/*entsconfig.json - Confirmar rutas relativas desde
process.cwd() - Verificar que los paquetes estén en
pnpm-workspace.yaml
Recursos
- Next.js Documentation
- Tailwind CSS v4
- Firebase Setup
- Monorepo Setup
- WORKFLOW.md – Flujo de desarrollo del equipo