Ir al contenido

Estructura de Rutas

El proyecto usa App Router de Next.js con route groups, locale prefixing y rutas dinámicas por workspace.

apps/web/app/
├── [locale]/ # Ruta dinámica para el locale
│ ├── (landing)/ # Route group — páginas públicas (landing)
│ │ ├── page.tsx # /[locale] → Home
│ │ ├── contact/page.tsx # /[locale]/contact
│ │ └── terms/page.tsx # /[locale]/terms
│ ├── (auth)/ # Route group — autenticación
│ │ ├── login/page.tsx # /[locale]/login
│ │ ├── register/page.tsx # /[locale]/register
│ │ └── forgot-password/page.tsx # /[locale]/forgot-password
│ ├── [...rest]/page.tsx # Catch-all → 404
│ ├── profile/ # Perfil global (standalone)
│ │ ├── page.tsx # /[locale]/profile
│ │ └── edit/page.tsx # /[locale]/profile/edit
│ ├── workspaces/ # Área autenticada con workspaces
│ │ page.tsx # /[locale]/workspaces → Listado
│ │ └── [workspaceId]/ # /[locale]/workspaces/:id
│ │ ├── layout.tsx # Layout del workspace
│ │ ├── home/page.tsx # /:id/home
│ │ ├── kanban/page.tsx # /:id/kanban (primer board)
│ │ ├── kanban/[boardId]/page.tsx # /:id/kanban/:boardId
│ │ ├── backlog/page.tsx # /:id/backlog
│ │ ├── calendar/page.tsx # /:id/calendar
│ │ ├── teams/page.tsx # /:id/teams
│ │ ├── chat/page.tsx # /:id/chat
│ │ ├── settings/page.tsx # /:id/settings
│ │ └── profile/ # Perfil dentro del workspace
│ │ ├── page.tsx
│ │ ├── edit/page.tsx
│ │ └── [id]/page.tsx
│ └── api/auth/[...nextauth]/ # API route de NextAuth
│ └── route.ts
└── layout.tsx # Root layout (html básico)

Perfiles: existen dos rutas de perfil. /[locale]/profile es el perfil global del usuario. /workspaces/[workspaceId]/profile mantiene la UI del workspace (sidebar/topbar), pero los datos son del usuario, no del workspace. /profile/[id] es la vista pública de otro usuario.

Los paréntesis (landing) y (auth) agrupan rutas sin afectar la URL.

Grupo Contenido Acceso
(landing) Home, contacto, términos y condiciones Público
(auth) Login / Register / Forgot password Público
[...rest] Catch-all para rutas inexistentes (404) Público

Nota: anteriormente existía un route group (workspace) que agrupaba las páginas internas sin afectar la URL. Fue reemplazado por el segmento real workspaces/[workspaceId] para que cada workspace tenga su propia URL.

La carpeta workspaces/[workspaceId] contiene el área autenticada. Cada workspace tiene su propia URL, lo que permite:

  • Trabajar con múltiples workspaces en pestañas diferentes sin conflictos de estado.
  • Compartir URLs directas a un workspace específico.
  • Validar la membresía del usuario en el layout dinámico.
Ruta real URL
/[locale]/workspaces/page.tsx /es/workspaces o /en/workspaces
/[locale]/workspaces/[workspaceId]/home/page.tsx /es/workspaces/ws-123/home
/[locale]/workspaces/[workspaceId]/kanban/page.tsx /es/workspaces/ws-123/kanban
/[locale]/workspaces/[workspaceId]/settings/page.tsx /es/workspaces/ws-123/settings

app/[locale]/workspaces/[workspaceId]/layout.tsx es un Server Component que:

  1. Recibe params.workspaceId.
  2. Verifica que el usuario autenticado sea miembro del workspace.
  3. Si no lo es, redirige a /[locale]/workspaces.
  4. Pasa los datos del workspace a Sidebar y TopBar.
export default async function WorkspaceLayout({
children,
params,
}: {
children: ReactNode;
params: Promise<{ workspaceId: string }>;
}) {
const { workspaceId } = await params;
// ...validar membresía y renderizar layout
}

/workspaces muestra todos los workspaces del usuario. Al hacer clic en uno, se navega a:

/[locale]/workspaces/[workspaceId]/home

Después del login, el usuario se redirige a /[locale]/workspaces para que elija o cree un workspace.

Añadir una ruta nueva dentro de un workspace

Sección titulada «Añadir una ruta nueva dentro de un workspace»
  1. Crear el archivo dentro de app/[locale]/workspaces/[workspaceId]/mi-ruta/page.tsx.
  2. Usar el componente Breadcrumbs para mantener la navegación.
  3. Construir links con el workspaceId disponible en el layout o via props.
Archivo Propósito
app/[locale]/workspaces/page.tsx Listado de workspaces
app/[locale]/workspaces/[workspaceId]/layout.tsx Layout dinámico con validación
components/layout/Sidebar.tsx Navegación lateral con links dinámicos + sección de boards
components/layout/TopBar.tsx Breadcrumb del workspace activo
components/layout/Breadcrumbs.tsx Migas de pan internas