Refactor: Analyze project documentation
This commit is contained in:
608
docs/DEVELOPMENT.md
Normal file
608
docs/DEVELOPMENT.md
Normal file
@@ -0,0 +1,608 @@
|
||||
# 🛠️ Guía de Desarrollo - Karibeo
|
||||
|
||||
## Configuración del Entorno
|
||||
|
||||
### Requisitos del Sistema
|
||||
|
||||
- **Node.js**: >= 18.0.0 (recomendado 20.x LTS)
|
||||
- **npm**: >= 9.0.0 o **yarn**: >= 1.22.0
|
||||
- **Git**: >= 2.30.0
|
||||
- **Editor**: VSCode (recomendado) con extensiones
|
||||
|
||||
### Extensiones VSCode Recomendadas
|
||||
|
||||
```json
|
||||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"formulahendry.auto-rename-tag",
|
||||
"christian-kohler.path-intellisense",
|
||||
"dsznajder.es7-react-js-snippets",
|
||||
"mikestead.dotenv"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Setup Inicial
|
||||
|
||||
### 1. Clonar el Repositorio
|
||||
|
||||
```bash
|
||||
git clone https://github.com/tu-usuario/karibeo.git
|
||||
cd karibeo
|
||||
```
|
||||
|
||||
### 2. Instalar Dependencias
|
||||
|
||||
```bash
|
||||
npm install
|
||||
# o
|
||||
yarn install
|
||||
```
|
||||
|
||||
### 3. Configurar Variables de Entorno
|
||||
|
||||
Crear archivo `.env` en la raíz:
|
||||
|
||||
```env
|
||||
# API Backend
|
||||
VITE_API_BASE_URL=https://karibeo.lesoluciones.net:8443/api/v1
|
||||
|
||||
# Google Maps
|
||||
VITE_GOOGLE_MAPS_API_KEY=your_google_maps_api_key
|
||||
|
||||
# Stripe (Pagos)
|
||||
VITE_STRIPE_PUBLIC_KEY=pk_test_...
|
||||
|
||||
# Analytics (Opcional)
|
||||
VITE_GA_ID=G-XXXXXXXXXX
|
||||
|
||||
# Sentry (Error Tracking - Opcional)
|
||||
VITE_SENTRY_DSN=https://...@sentry.io/...
|
||||
|
||||
# Feature Flags (Opcional)
|
||||
VITE_ENABLE_ANALYTICS=true
|
||||
VITE_ENABLE_PWA=false
|
||||
```
|
||||
|
||||
### 4. Iniciar Servidor de Desarrollo
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
La aplicación estará disponible en: `http://localhost:5173`
|
||||
|
||||
## Estructura de Carpetas Detallada
|
||||
|
||||
```
|
||||
karibeo/
|
||||
├── .vscode/ # Configuración de VSCode
|
||||
│ ├── settings.json # Configuraciones del workspace
|
||||
│ └── extensions.json # Extensiones recomendadas
|
||||
│
|
||||
├── docs/ # Documentación
|
||||
│ ├── API.md # Documentación de API
|
||||
│ ├── ARCHITECTURE.md # Arquitectura del sistema
|
||||
│ └── DEVELOPMENT.md # Esta guía
|
||||
│
|
||||
├── public/ # Assets estáticos
|
||||
│ ├── favicon.ico
|
||||
│ ├── manifest.json # PWA manifest
|
||||
│ └── robots.txt
|
||||
│
|
||||
├── src/
|
||||
│ ├── assets/ # Recursos (imágenes, fonts)
|
||||
│ │ ├── images/
|
||||
│ │ └── fonts/
|
||||
│ │
|
||||
│ ├── components/ # Componentes React
|
||||
│ │ ├── ui/ # Componentes base (shadcn)
|
||||
│ │ │ ├── button.tsx
|
||||
│ │ │ ├── input.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ │
|
||||
│ │ ├── admin/ # Componentes de admin
|
||||
│ │ │ ├── ConfigTab.tsx
|
||||
│ │ │ ├── UsersTab.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ │
|
||||
│ │ ├── hotel/ # Componentes hoteleros
|
||||
│ │ ├── restaurant/ # Componentes de restaurante
|
||||
│ │ ├── roles/ # Sistema de roles
|
||||
│ │ ├── security/ # Componentes de seguridad
|
||||
│ │ └── shared/ # Componentes compartidos
|
||||
│ │
|
||||
│ ├── contexts/ # React Contexts
|
||||
│ │ ├── AuthContext.tsx
|
||||
│ │ ├── CartContext.tsx
|
||||
│ │ ├── CurrencyContext.tsx
|
||||
│ │ └── LanguageContext.tsx
|
||||
│ │
|
||||
│ ├── hooks/ # Custom Hooks
|
||||
│ │ ├── useAdminData.ts
|
||||
│ │ ├── useBooking.ts
|
||||
│ │ ├── useChannelManager.ts
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ ├── lib/ # Utilidades y helpers
|
||||
│ │ ├── utils.ts # Funciones utilitarias
|
||||
│ │ └── validation.ts # Schemas de validación
|
||||
│ │
|
||||
│ ├── pages/ # Páginas/Rutas
|
||||
│ │ ├── dashboard/ # Panel de control
|
||||
│ │ │ ├── AdminDashboard.tsx
|
||||
│ │ │ ├── Dashboard.tsx
|
||||
│ │ │ └── ...
|
||||
│ │ │
|
||||
│ │ ├── Index.tsx # Landing page
|
||||
│ │ ├── SignIn.tsx # Login
|
||||
│ │ └── SignUp.tsx # Registro
|
||||
│ │
|
||||
│ ├── services/ # Servicios API
|
||||
│ │ ├── adminApi.ts
|
||||
│ │ ├── emergencyApi.ts
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ ├── types/ # TypeScript types
|
||||
│ │ ├── index.ts
|
||||
│ │ └── roles.ts
|
||||
│ │
|
||||
│ ├── i18n/ # Internacionalización
|
||||
│ │ ├── en.ts
|
||||
│ │ └── es.ts
|
||||
│ │
|
||||
│ ├── App.tsx # Componente principal
|
||||
│ ├── main.tsx # Entry point
|
||||
│ └── index.css # Estilos globales
|
||||
│
|
||||
├── .eslintrc.js # Configuración ESLint
|
||||
├── .prettierrc # Configuración Prettier
|
||||
├── tailwind.config.ts # Configuración Tailwind
|
||||
├── tsconfig.json # Configuración TypeScript
|
||||
├── vite.config.ts # Configuración Vite
|
||||
└── package.json # Dependencias y scripts
|
||||
```
|
||||
|
||||
## Convenciones de Código
|
||||
|
||||
### Nomenclatura
|
||||
|
||||
#### Archivos
|
||||
```typescript
|
||||
// PascalCase para componentes
|
||||
UserProfile.tsx
|
||||
AdminDashboard.tsx
|
||||
|
||||
// camelCase para utilidades y hooks
|
||||
useAuth.ts
|
||||
formatCurrency.ts
|
||||
|
||||
// kebab-case para estilos
|
||||
user-profile.css
|
||||
```
|
||||
|
||||
#### Variables y Funciones
|
||||
```typescript
|
||||
// camelCase para variables y funciones
|
||||
const userName = "John";
|
||||
function getUserData() {}
|
||||
|
||||
// PascalCase para componentes y clases
|
||||
const UserCard = () => {};
|
||||
class ApiClient {}
|
||||
|
||||
// UPPER_SNAKE_CASE para constantes
|
||||
const MAX_RETRY_ATTEMPTS = 3;
|
||||
const API_BASE_URL = "https://...";
|
||||
```
|
||||
|
||||
#### Interfaces y Types
|
||||
```typescript
|
||||
// PascalCase con prefijo "I" opcional
|
||||
interface UserProfile {}
|
||||
interface IUserProfile {} // alternativa
|
||||
|
||||
type UserRole = 'admin' | 'user';
|
||||
```
|
||||
|
||||
### Formato de Código
|
||||
|
||||
#### Imports
|
||||
```typescript
|
||||
// 1. Imports de librerías externas
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
// 2. Imports de componentes UI
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
|
||||
// 3. Imports de componentes propios
|
||||
import { UserCard } from '@/components/UserCard';
|
||||
|
||||
// 4. Imports de hooks y contexts
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
import { useAdminData } from '@/hooks/useAdminData';
|
||||
|
||||
// 5. Imports de utilidades y tipos
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { User } from '@/types';
|
||||
|
||||
// 6. Imports de assets
|
||||
import logo from '@/assets/logo.png';
|
||||
|
||||
// 7. Imports de estilos
|
||||
import './styles.css';
|
||||
```
|
||||
|
||||
#### Componentes Funcionales
|
||||
```typescript
|
||||
// Buena práctica
|
||||
interface UserCardProps {
|
||||
user: User;
|
||||
onEdit?: (id: string) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const UserCard: React.FC<UserCardProps> = ({
|
||||
user,
|
||||
onEdit,
|
||||
className
|
||||
}) => {
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Effect logic
|
||||
}, []);
|
||||
|
||||
const handleClick = () => {
|
||||
setIsExpanded(!isExpanded);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn("card", className)}>
|
||||
{/* JSX */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
#### Tipado Estricto
|
||||
```typescript
|
||||
// ✅ Bueno
|
||||
interface User {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
const getUser = (id: string): Promise<User> => {
|
||||
return api.get<User>(`/users/${id}`);
|
||||
};
|
||||
|
||||
// ❌ Evitar
|
||||
const getUser = (id: any): any => {
|
||||
return api.get(`/users/${id}`);
|
||||
};
|
||||
```
|
||||
|
||||
#### Usar Interfaces sobre Types
|
||||
```typescript
|
||||
// ✅ Preferido para objetos
|
||||
interface UserProfile {
|
||||
name: string;
|
||||
age: number;
|
||||
}
|
||||
|
||||
// ✅ Usar type para unions, intersections
|
||||
type UserRole = 'admin' | 'user' | 'guest';
|
||||
type ExtendedUser = UserProfile & { role: UserRole };
|
||||
```
|
||||
|
||||
### React Patterns
|
||||
|
||||
#### Hooks
|
||||
```typescript
|
||||
// Custom hook
|
||||
export const useUser = (userId: string) => {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUser(userId)
|
||||
.then(setUser)
|
||||
.catch(setError)
|
||||
.finally(() => setLoading(false));
|
||||
}, [userId]);
|
||||
|
||||
return { user, loading, error };
|
||||
};
|
||||
```
|
||||
|
||||
#### Memoization
|
||||
```typescript
|
||||
// useMemo para cálculos costosos
|
||||
const expensiveValue = useMemo(() => {
|
||||
return computeExpensiveValue(a, b);
|
||||
}, [a, b]);
|
||||
|
||||
// useCallback para funciones
|
||||
const handleSubmit = useCallback((data: FormData) => {
|
||||
submitForm(data);
|
||||
}, []);
|
||||
|
||||
// memo para componentes
|
||||
export const UserCard = memo(({ user }: Props) => {
|
||||
return <div>{user.name}</div>;
|
||||
});
|
||||
```
|
||||
|
||||
### Tailwind CSS
|
||||
|
||||
#### Ordenamiento de Clases
|
||||
```tsx
|
||||
// Orden recomendado:
|
||||
// 1. Layout (display, position)
|
||||
// 2. Box model (width, height, margin, padding)
|
||||
// 3. Typography
|
||||
// 4. Visual (background, border, shadow)
|
||||
// 5. Misc (cursor, transform, transition)
|
||||
|
||||
<div className="
|
||||
flex items-center justify-between
|
||||
w-full h-20 p-4
|
||||
text-lg font-semibold
|
||||
bg-white border border-gray-200 rounded-lg shadow-md
|
||||
hover:shadow-lg transition-shadow
|
||||
">
|
||||
Content
|
||||
</div>
|
||||
```
|
||||
|
||||
#### Usar cn() para Clases Condicionales
|
||||
```tsx
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
<Button
|
||||
className={cn(
|
||||
"base-class",
|
||||
isActive && "active-class",
|
||||
isDisabled && "disabled-class",
|
||||
customClass
|
||||
)}
|
||||
/>
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Jest + React Testing Library
|
||||
|
||||
#### Setup
|
||||
```bash
|
||||
npm install --save-dev @testing-library/react @testing-library/jest-dom jest
|
||||
```
|
||||
|
||||
#### Escribir Tests
|
||||
```typescript
|
||||
// UserCard.test.tsx
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { UserCard } from './UserCard';
|
||||
|
||||
describe('UserCard', () => {
|
||||
const mockUser = {
|
||||
id: '1',
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com'
|
||||
};
|
||||
|
||||
it('renders user information', () => {
|
||||
render(<UserCard user={mockUser} />);
|
||||
expect(screen.getByText('John Doe')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls onEdit when edit button is clicked', () => {
|
||||
const onEdit = jest.fn();
|
||||
render(<UserCard user={mockUser} onEdit={onEdit} />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /edit/i }));
|
||||
expect(onEdit).toHaveBeenCalledWith('1');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Ejecutar Tests
|
||||
```bash
|
||||
npm run test # Ejecutar todos los tests
|
||||
npm run test:watch # Watch mode
|
||||
npm run test:coverage # Con coverage
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### React Developer Tools
|
||||
Instalar extensión de navegador: React Developer Tools
|
||||
|
||||
### VSCode Debugging
|
||||
Crear `.vscode/launch.json`:
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch Chrome",
|
||||
"url": "http://localhost:5173",
|
||||
"webRoot": "${workspaceFolder}/src"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Console Logs Útiles
|
||||
```typescript
|
||||
// Debug con contexto
|
||||
console.log('🔍 User data:', user);
|
||||
console.error('❌ Error:', error);
|
||||
console.warn('⚠️ Warning:', warning);
|
||||
|
||||
// Grupos
|
||||
console.group('API Request');
|
||||
console.log('URL:', url);
|
||||
console.log('Method:', method);
|
||||
console.groupEnd();
|
||||
|
||||
// Tiempo de ejecución
|
||||
console.time('fetchData');
|
||||
await fetchData();
|
||||
console.timeEnd('fetchData');
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
### Optimizaciones
|
||||
|
||||
#### Code Splitting
|
||||
```typescript
|
||||
// Lazy loading de componentes
|
||||
const AdminDashboard = lazy(() => import('./pages/AdminDashboard'));
|
||||
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<AdminDashboard />
|
||||
</Suspense>
|
||||
```
|
||||
|
||||
#### Bundle Analysis
|
||||
```bash
|
||||
npm run build
|
||||
npm run analyze
|
||||
```
|
||||
|
||||
#### Lighthouse CI
|
||||
```bash
|
||||
npm install -g @lhci/cli
|
||||
lhci autorun
|
||||
```
|
||||
|
||||
## Git Workflow
|
||||
|
||||
### Branches
|
||||
```
|
||||
main # Producción
|
||||
develop # Desarrollo
|
||||
feature/xxx # Nuevas características
|
||||
bugfix/xxx # Corrección de bugs
|
||||
hotfix/xxx # Hotfixes urgentes
|
||||
```
|
||||
|
||||
### Commits
|
||||
Usar convención de commits semánticos:
|
||||
```bash
|
||||
feat: add user authentication
|
||||
fix: resolve booking calculation bug
|
||||
docs: update API documentation
|
||||
style: format code with prettier
|
||||
refactor: reorganize admin components
|
||||
test: add tests for UserCard component
|
||||
chore: update dependencies
|
||||
```
|
||||
|
||||
### Pull Requests
|
||||
1. Crear branch desde `develop`
|
||||
2. Hacer cambios y commits
|
||||
3. Push al repositorio remoto
|
||||
4. Crear PR hacia `develop`
|
||||
5. Code review
|
||||
6. Merge después de aprobación
|
||||
|
||||
## Build y Deploy
|
||||
|
||||
### Build Local
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
Archivos generados en `/dist`
|
||||
|
||||
### Preview Build
|
||||
```bash
|
||||
npm run preview
|
||||
```
|
||||
|
||||
### Deploy a Lovable
|
||||
1. Commit y push cambios
|
||||
2. Ir a proyecto en Lovable
|
||||
3. Cambios se sincronizarán automáticamente
|
||||
|
||||
### Deploy Manual
|
||||
```bash
|
||||
# Vercel
|
||||
vercel deploy
|
||||
|
||||
# Netlify
|
||||
netlify deploy --prod
|
||||
|
||||
# AWS S3
|
||||
aws s3 sync dist/ s3://your-bucket/
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problemas Comunes
|
||||
|
||||
#### Puerto 5173 en uso
|
||||
```bash
|
||||
# Cambiar puerto en vite.config.ts
|
||||
export default defineConfig({
|
||||
server: {
|
||||
port: 3000
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### Problemas con node_modules
|
||||
```bash
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
```
|
||||
|
||||
#### Errores de TypeScript
|
||||
```bash
|
||||
# Limpiar cache
|
||||
rm -rf node_modules/.vite
|
||||
npm run dev
|
||||
```
|
||||
|
||||
#### Build falla
|
||||
```bash
|
||||
# Verificar errores
|
||||
npm run build 2>&1 | tee build.log
|
||||
|
||||
# Limpiar y rebuild
|
||||
rm -rf dist
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
### Documentación Oficial
|
||||
- [React](https://react.dev/)
|
||||
- [TypeScript](https://www.typescriptlang.org/docs/)
|
||||
- [Vite](https://vitejs.dev/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/docs)
|
||||
- [shadcn/ui](https://ui.shadcn.com/)
|
||||
|
||||
### Comunidad
|
||||
- [Karibeo Discord](#)
|
||||
- [GitHub Discussions](#)
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/karibeo)
|
||||
|
||||
---
|
||||
|
||||
**Última actualización**: 2025-01-12
|
||||
Reference in New Issue
Block a user