ar-saas 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +338 -314
  3. package/dist/cli.js +19 -0
  4. package/dist/generator.js +166 -55
  5. package/package.json +52 -50
  6. package/templates/backend/.env.example +67 -67
  7. package/templates/backend/.prettierrc +4 -4
  8. package/templates/backend/README.md +249 -168
  9. package/templates/backend/eslint.config.mjs +35 -35
  10. package/templates/backend/nest-cli.json +8 -8
  11. package/templates/backend/package-lock.json +10979 -10979
  12. package/templates/backend/package.json +88 -88
  13. package/templates/backend/src/app.controller.spec.ts +24 -24
  14. package/templates/backend/src/app.controller.ts +15 -15
  15. package/templates/backend/src/app.module.ts +40 -40
  16. package/templates/backend/src/app.service.ts +11 -11
  17. package/templates/backend/src/common/base/base.repository.ts +221 -221
  18. package/templates/backend/src/common/base/base.schema.ts +24 -24
  19. package/templates/backend/src/common/decorators/cookie.decorator.ts +9 -9
  20. package/templates/backend/src/common/decorators/current-user.decorator.ts +20 -20
  21. package/templates/backend/src/common/decorators/workspace-id.decorator.ts +14 -14
  22. package/templates/backend/src/common/filters/global-exception.filter.ts +61 -61
  23. package/templates/backend/src/common/guards/jwt-auth.guard.ts +5 -5
  24. package/templates/backend/src/common/interceptors/workspace-tenant.interceptor.ts +45 -45
  25. package/templates/backend/src/main.ts +51 -51
  26. package/templates/backend/src/modules/auth/auth.controller.ts +158 -158
  27. package/templates/backend/src/modules/auth/auth.module.ts +20 -20
  28. package/templates/backend/src/modules/auth/auth.service.ts +257 -257
  29. package/templates/backend/src/modules/auth/dto/forgot-password.dto.ts +9 -9
  30. package/templates/backend/src/modules/auth/dto/login.dto.ts +14 -14
  31. package/templates/backend/src/modules/auth/dto/refresh-token.dto.ts +12 -12
  32. package/templates/backend/src/modules/auth/dto/register.dto.ts +26 -26
  33. package/templates/backend/src/modules/auth/dto/reset-password.dto.ts +16 -16
  34. package/templates/backend/src/modules/auth/dto/verify-email.dto.ts +9 -9
  35. package/templates/backend/src/modules/auth/strategies/jwt.strategy.ts +43 -43
  36. package/templates/backend/src/modules/mail/mail.module.ts +9 -9
  37. package/templates/backend/src/modules/mail/mail.service.ts +141 -141
  38. package/templates/backend/src/modules/users/schemas/user.schema.ts +54 -54
  39. package/templates/backend/src/modules/users/users.module.ts +14 -14
  40. package/templates/backend/src/modules/users/users.repository.ts +51 -51
  41. package/templates/backend/src/modules/users/users.service.ts +104 -104
  42. package/templates/backend/src/modules/workspaces/schemas/workspace.schema.ts +26 -26
  43. package/templates/backend/src/modules/workspaces/workspaces.module.ts +16 -16
  44. package/templates/backend/src/modules/workspaces/workspaces.repository.ts +34 -34
  45. package/templates/backend/src/modules/workspaces/workspaces.service.ts +42 -42
  46. package/templates/backend/test/app.e2e-spec.ts +25 -25
  47. package/templates/backend/test/jest-e2e.json +9 -9
  48. package/templates/backend/tsconfig.build.json +4 -4
  49. package/templates/backend/tsconfig.json +26 -26
  50. package/templates/frontend/.env.local.example +1 -1
  51. package/templates/frontend/README.md +152 -0
  52. package/templates/frontend/components.json +20 -20
  53. package/templates/frontend/eslint.config.mjs +14 -14
  54. package/templates/frontend/next.config.ts +5 -5
  55. package/templates/frontend/package-lock.json +6722 -6722
  56. package/templates/frontend/package.json +48 -48
  57. package/templates/frontend/pnpm-lock.yaml +5012 -5012
  58. package/templates/frontend/pnpm-workspace.yaml +3 -3
  59. package/templates/frontend/postcss.config.mjs +7 -7
  60. package/templates/frontend/src/app/(auth)/forgot-password/page.tsx +84 -84
  61. package/templates/frontend/src/app/(auth)/layout.tsx +28 -28
  62. package/templates/frontend/src/app/(auth)/login/page.tsx +111 -111
  63. package/templates/frontend/src/app/(auth)/register/page.tsx +161 -161
  64. package/templates/frontend/src/app/(auth)/reset-password/page.tsx +120 -120
  65. package/templates/frontend/src/app/(auth)/verify-email/page.tsx +78 -78
  66. package/templates/frontend/src/app/(dashboard)/billing/page.tsx +111 -111
  67. package/templates/frontend/src/app/(dashboard)/dashboard/page.tsx +105 -105
  68. package/templates/frontend/src/app/(dashboard)/layout.tsx +38 -38
  69. package/templates/frontend/src/app/(dashboard)/profile/page.tsx +226 -226
  70. package/templates/frontend/src/app/(dashboard)/settings/page.tsx +156 -156
  71. package/templates/frontend/src/app/(dashboard)/team/page.tsx +178 -178
  72. package/templates/frontend/src/app/(legal)/privacy/page.tsx +127 -127
  73. package/templates/frontend/src/app/(legal)/terms/page.tsx +118 -118
  74. package/templates/frontend/src/app/globals.css +81 -81
  75. package/templates/frontend/src/app/layout.tsx +26 -26
  76. package/templates/frontend/src/app/page.tsx +5 -45
  77. package/templates/frontend/src/app/setup/page.tsx +371 -275
  78. package/templates/frontend/src/components/dashboard/header.tsx +89 -89
  79. package/templates/frontend/src/components/dashboard/sidebar.tsx +71 -71
  80. package/templates/frontend/src/components/dashboard/stat-card.tsx +34 -34
  81. package/templates/frontend/src/components/landing/faq.tsx +39 -39
  82. package/templates/frontend/src/components/landing/features.tsx +54 -54
  83. package/templates/frontend/src/components/landing/footer.tsx +76 -76
  84. package/templates/frontend/src/components/landing/hero.tsx +72 -72
  85. package/templates/frontend/src/components/landing/navbar.tsx +78 -78
  86. package/templates/frontend/src/components/landing/pricing.tsx +90 -90
  87. package/templates/frontend/src/components/ui/accordion.tsx +52 -52
  88. package/templates/frontend/src/components/ui/avatar.tsx +46 -46
  89. package/templates/frontend/src/components/ui/badge.tsx +30 -30
  90. package/templates/frontend/src/components/ui/button.tsx +52 -52
  91. package/templates/frontend/src/components/ui/card.tsx +50 -50
  92. package/templates/frontend/src/components/ui/checkbox.tsx +27 -27
  93. package/templates/frontend/src/components/ui/dialog.tsx +100 -100
  94. package/templates/frontend/src/components/ui/dropdown-menu.tsx +173 -173
  95. package/templates/frontend/src/components/ui/form.tsx +158 -158
  96. package/templates/frontend/src/components/ui/input.tsx +21 -21
  97. package/templates/frontend/src/components/ui/label.tsx +22 -22
  98. package/templates/frontend/src/components/ui/separator.tsx +25 -25
  99. package/templates/frontend/src/components/ui/skeleton.tsx +7 -7
  100. package/templates/frontend/src/components/ui/switch.tsx +28 -28
  101. package/templates/frontend/src/components/ui/tabs.tsx +54 -54
  102. package/templates/frontend/src/components/ui/textarea.tsx +20 -20
  103. package/templates/frontend/src/components/ui/toast.tsx +109 -109
  104. package/templates/frontend/src/components/ui/toaster.tsx +30 -30
  105. package/templates/frontend/src/config/site.ts +197 -197
  106. package/templates/frontend/src/hooks/use-toast.ts +116 -116
  107. package/templates/frontend/src/lib/api/auth.ts +39 -39
  108. package/templates/frontend/src/lib/api/client.ts +66 -66
  109. package/templates/frontend/src/lib/hooks/use-auth.ts +1 -1
  110. package/templates/frontend/src/lib/utils.ts +6 -6
  111. package/templates/frontend/src/providers/auth-provider.tsx +60 -60
  112. package/templates/frontend/src/types/api.ts +12 -12
  113. package/templates/frontend/src/types/auth.ts +27 -27
  114. package/templates/frontend/tsconfig.json +23 -23
@@ -1,26 +1,26 @@
1
- {
2
- "compilerOptions": {
3
- "module": "nodenext",
4
- "moduleResolution": "nodenext",
5
- "resolvePackageJsonExports": true,
6
- "esModuleInterop": true,
7
- "isolatedModules": true,
8
- "declaration": true,
9
- "removeComments": true,
10
- "emitDecoratorMetadata": true,
11
- "experimentalDecorators": true,
12
- "allowSyntheticDefaultImports": true,
13
- "target": "ES2023",
14
- "sourceMap": true,
15
- "outDir": "./dist",
16
- "baseUrl": "./",
17
- "incremental": true,
18
- "skipLibCheck": true,
19
- "strict": true,
20
- "forceConsistentCasingInFileNames": true,
21
- "noImplicitAny": true,
22
- "strictNullChecks": true,
23
- "strictBindCallApply": true,
24
- "noFallthroughCasesInSwitch": true
25
- }
26
- }
1
+ {
2
+ "compilerOptions": {
3
+ "module": "nodenext",
4
+ "moduleResolution": "nodenext",
5
+ "resolvePackageJsonExports": true,
6
+ "esModuleInterop": true,
7
+ "isolatedModules": true,
8
+ "declaration": true,
9
+ "removeComments": true,
10
+ "emitDecoratorMetadata": true,
11
+ "experimentalDecorators": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "target": "ES2023",
14
+ "sourceMap": true,
15
+ "outDir": "./dist",
16
+ "baseUrl": "./",
17
+ "incremental": true,
18
+ "skipLibCheck": true,
19
+ "strict": true,
20
+ "forceConsistentCasingInFileNames": true,
21
+ "noImplicitAny": true,
22
+ "strictNullChecks": true,
23
+ "strictBindCallApply": true,
24
+ "noFallthroughCasesInSwitch": true
25
+ }
26
+ }
@@ -1 +1 @@
1
- NEXT_PUBLIC_API_URL=http://localhost:3000
1
+ NEXT_PUBLIC_API_URL=http://localhost:3000
@@ -0,0 +1,152 @@
1
+ # create-saas-ar — Frontend
2
+
3
+ Frontend del template SaaS para startups argentinas. Stack: Next.js 15, TypeScript, Tailwind CSS 4, shadcn/ui.
4
+
5
+ ---
6
+
7
+ ## Stack
8
+
9
+ | Capa | Tecnología |
10
+ |---|---|
11
+ | Framework | Next.js 15 (App Router) |
12
+ | Lenguaje | TypeScript (strict) |
13
+ | Estilos | Tailwind CSS 4 |
14
+ | Componentes UI | shadcn/ui |
15
+ | Formularios | react-hook-form |
16
+ | HTTP | axios (con interceptor de refresh automático) |
17
+ | Auth | Cookies HttpOnly — tokens manejados por el backend |
18
+
19
+ ---
20
+
21
+ ## Prerequisitos
22
+
23
+ - Node.js 20 LTS o superior
24
+ - El backend corriendo en `http://localhost:3000` (o la URL configurada en `NEXT_PUBLIC_API_URL`)
25
+ - MongoDB corriendo (ver instrucciones en el README del backend)
26
+
27
+ ---
28
+
29
+ ## Setup inicial
30
+
31
+ ### 1. Instalar dependencias
32
+
33
+ ```bash
34
+ cd frontend
35
+ npm install
36
+ ```
37
+
38
+ ### 2. Configurar variables de entorno
39
+
40
+ ```bash
41
+ # El generador ya copió .env.local.example → .env.local automáticamente
42
+ # Solo verificar que el valor sea correcto:
43
+ cat .env.local
44
+ ```
45
+
46
+ | Variable | Descripción | Valor por defecto |
47
+ |---|---|---|
48
+ | `NEXT_PUBLIC_API_URL` | URL base del backend | `http://localhost:3000` |
49
+
50
+ Si cambiaste el puerto del backend, actualizá este valor.
51
+
52
+ ### 3. Levantar el backend primero
53
+
54
+ El frontend depende del backend para autenticación. Antes de arrancar el frontend, asegurate de que el backend esté corriendo:
55
+
56
+ ```bash
57
+ # En otra terminal
58
+ cd backend
59
+ npm run start:dev
60
+ # Verificar: http://localhost:3000/api/docs debe cargar
61
+ ```
62
+
63
+ Para levantar MongoDB antes del backend, ver las instrucciones en `backend/README.md` o ejecutar:
64
+
65
+ ```bash
66
+ # Desde la raíz del proyecto
67
+ docker compose -f docker-compose.dev.yml up -d
68
+ ```
69
+
70
+ ### 4. Iniciar el frontend
71
+
72
+ ```bash
73
+ npm run dev
74
+ ```
75
+
76
+ El frontend levanta en `http://localhost:3001`. Al abrirlo por primera vez verás la pantalla de setup con instrucciones paso a paso.
77
+
78
+ ---
79
+
80
+ ## Comandos disponibles
81
+
82
+ ```bash
83
+ npm run dev # Servidor de desarrollo con hot reload
84
+ npm run build # Build de producción
85
+ npm run start # Servidor de producción (requiere build previo)
86
+ npm run lint # ESLint
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Estructura de carpetas
92
+
93
+ ```
94
+ src/
95
+ ├── app/
96
+ │ ├── (auth)/ # Login, registro, verificación de email, reset de contraseña
97
+ │ ├── (dashboard)/ # Rutas protegidas (dashboard, perfil, billing, equipo)
98
+ │ ├── (legal)/ # Términos y privacidad
99
+ │ ├── setup/ # Pantalla de setup inicial (se muestra al arrancar por primera vez)
100
+ │ ├── layout.tsx # Layout raíz con AuthProvider
101
+ │ └── page.tsx # Redirige a /setup
102
+ ├── components/
103
+ │ ├── landing/ # Componentes de la landing page (navbar, hero, features, pricing)
104
+ │ ├── dashboard/ # Sidebar, header y cards del dashboard
105
+ │ └── ui/ # Componentes shadcn/ui (no modificar directamente)
106
+ ├── config/
107
+ │ └── site.ts # Configuración centralizada de contenido del sitio
108
+ ├── lib/
109
+ │ ├── api/
110
+ │ │ ├── client.ts # Instancia axios con interceptor de 401 → refresh automático
111
+ │ │ └── auth.ts # Métodos de API de autenticación
112
+ │ └── hooks/
113
+ │ └── use-auth.ts # Hook para acceder al estado de auth
114
+ ├── providers/
115
+ │ └── auth-provider.tsx # Contexto global de auth (login, logout, register, estado)
116
+ └── types/ # Interfaces TypeScript (User, Workspace, ApiError, etc.)
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Personalizar el contenido del sitio
122
+
123
+ Todo el contenido de la landing page (nombre, tagline, features, precios, FAQ) está centralizado en [`src/config/site.ts`](src/config/site.ts).
124
+
125
+ Los valores con formato `__PLACEHOLDER__` son reemplazados automáticamente por el generador al crear el proyecto. Para personalizarlos manualmente:
126
+
127
+ ```typescript
128
+ // src/config/site.ts
129
+ export const siteConfig = {
130
+ name: 'Mi SaaS',
131
+ tagline: 'La descripción corta de tu producto',
132
+ description: 'Descripción larga para SEO',
133
+ supportEmail: 'soporte@midominio.com',
134
+ // ... pricing, features, FAQ, etc.
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Rutas protegidas
141
+
142
+ Las rutas bajo `(dashboard)/` requieren autenticación. Si el usuario no está logueado, es redirigido a `/login` automáticamente (manejado en el layout del grupo, sin middleware).
143
+
144
+ Para agregar nuevas rutas protegidas, crear la carpeta dentro de `src/app/(dashboard)/`.
145
+
146
+ ---
147
+
148
+ ## Autenticación
149
+
150
+ - Tokens JWT en cookies HttpOnly — el frontend nunca lee ni guarda tokens.
151
+ - `useAuth()` expone `user`, `isAuthenticated`, `isLoading`, `login()`, `logout()`, `register()`.
152
+ - El cliente axios renueva el access token automáticamente cuando recibe un 401.
@@ -1,20 +1,20 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "default",
4
- "rsc": true,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "",
8
- "css": "src/app/globals.css",
9
- "baseColor": "slate",
10
- "cssVariables": true
11
- },
12
- "aliases": {
13
- "components": "@/components",
14
- "utils": "@/lib/utils",
15
- "ui": "@/components/ui",
16
- "lib": "@/lib",
17
- "hooks": "@/hooks"
18
- },
19
- "iconLibrary": "lucide"
20
- }
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "default",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "",
8
+ "css": "src/app/globals.css",
9
+ "baseColor": "slate",
10
+ "cssVariables": true
11
+ },
12
+ "aliases": {
13
+ "components": "@/components",
14
+ "utils": "@/lib/utils",
15
+ "ui": "@/components/ui",
16
+ "lib": "@/lib",
17
+ "hooks": "@/hooks"
18
+ },
19
+ "iconLibrary": "lucide"
20
+ }
@@ -1,14 +1,14 @@
1
- import { dirname } from 'path'
2
- import { fileURLToPath } from 'url'
3
- import { FlatCompat } from '@eslint/eslintrc'
4
-
5
- const __filename = fileURLToPath(import.meta.url)
6
- const __dirname = dirname(__filename)
7
-
8
- const compat = new FlatCompat({ baseDirectory: __dirname })
9
-
10
- const eslintConfig = [
11
- ...compat.extends('next/core-web-vitals', 'next/typescript'),
12
- ]
13
-
14
- export default eslintConfig
1
+ import { dirname } from 'path'
2
+ import { fileURLToPath } from 'url'
3
+ import { FlatCompat } from '@eslint/eslintrc'
4
+
5
+ const __filename = fileURLToPath(import.meta.url)
6
+ const __dirname = dirname(__filename)
7
+
8
+ const compat = new FlatCompat({ baseDirectory: __dirname })
9
+
10
+ const eslintConfig = [
11
+ ...compat.extends('next/core-web-vitals', 'next/typescript'),
12
+ ]
13
+
14
+ export default eslintConfig
@@ -1,5 +1,5 @@
1
- import type { NextConfig } from 'next'
2
-
3
- const nextConfig: NextConfig = {}
4
-
5
- export default nextConfig
1
+ import type { NextConfig } from 'next'
2
+
3
+ const nextConfig: NextConfig = {}
4
+
5
+ export default nextConfig