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

CapaTecnologíaVersión
FrameworkNext.js (App Router)16.1.7
RuntimeNode.js 20+ (compatible con Firebase)
LenguajeTypeScript5.9.2
UI/StylingTailwind 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ónZod (a través de @repo/schemas)
AnimacionesTailwind Animate (tailwindcss-animate)1.0.7
TestingVitest (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:

json
{
  "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:

tsx
// ✅ 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):

typescript
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:

javascript
export default {
  plugins: {
    tailwindcss: {},
  },
};

4.4 ESLint (eslint.config.mjs)

Extiende la configuración base de Rappid Tech:

javascript
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:

css
@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):

css
/* 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)

tsx
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)

tsx
import { ChevronDown, Settings } from '@repo/icons';

export function Header() {
  return (
    <button>
      <Settings size={20} />
    </button>
  );
}

5.3 Constantes (@repo/constants)

tsx
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)

tsx
import { useIsMobile } from '@repo/hooks';

export function ResponsiveComponent() {
  const isMobile = useIsMobile();

  return isMobile ? <MobileLayout /> : <DesktopLayout />;
}

5.5 Esquemas y Validación (@repo/schemas)

tsx
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)

tsx
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:

typescript
// 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/:

tsx
import { LogoNidus } from '@repo/icons';

export function Header() {
  return <LogoNidus size={40} />;
}

7. Desarrollo

7.1 Instalación y Setup

bash
# Desde la raíz del monorepo
pnpm install

# Verificar tipos
pnpm check-types

# Verificar linting
pnpm lint

7.2 Correr en Desarrollo

bash
# 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

bash
# 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

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:

env
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

bash
# 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

bash
# 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)

bash
# 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.json con nombre único
  • tsconfig.json extendiendo @repo/tsconfig
  • next.config.ts (puede estar vacío)
  • postcss.config.mjs con Tailwind
  • eslint.config.mjs extendiendo @repo/eslint
  • app/layout.tsx con estructura básica
  • app/page.tsx con contenido inicial
  • app/globals.css con imports de Tailwind
  • Variables de entorno en .env.local
  • apphosting.test.yaml para deploy
  • README.md con documentación específica de la app
  • Agregar a pnpm-workspace.yaml si 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

tsx
// ✅ 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

bash
# Limpiar node_modules y cache
pnpm clean
pnpm install

# Verificar tipos
pnpm check-types

Tailwind CSS no aplica estilos

  1. Verificar que globals.css esté importado en layout.tsx
  2. Confirmar @source apunta a @repo/ui correctamente
  3. Limpiar .next/: rm -rf .next && pnpm dev

Imports fallando

  1. Verificar alias @/* en tsconfig.json
  2. Confirmar rutas relativas desde process.cwd()
  3. Verificar que los paquetes estén en pnpm-workspace.yaml

Recursos