nexu-app 2.0.0

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 (106) hide show
  1. package/README.md +149 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +1192 -0
  4. package/package.json +43 -0
  5. package/templates/default/.changeset/config.json +11 -0
  6. package/templates/default/.eslintignore +16 -0
  7. package/templates/default/.eslintrc.js +67 -0
  8. package/templates/default/.github/actions/build/action.yml +35 -0
  9. package/templates/default/.github/actions/quality/action.yml +53 -0
  10. package/templates/default/.github/dependabot.yml +51 -0
  11. package/templates/default/.github/workflows/deploy-dev.yml +83 -0
  12. package/templates/default/.github/workflows/deploy-prod.yml +83 -0
  13. package/templates/default/.github/workflows/deploy-rec.yml +83 -0
  14. package/templates/default/.husky/commit-msg +1 -0
  15. package/templates/default/.husky/pre-commit +1 -0
  16. package/templates/default/.nexu-version +1 -0
  17. package/templates/default/.prettierignore +7 -0
  18. package/templates/default/.prettierrc +19 -0
  19. package/templates/default/.vscode/extensions.json +14 -0
  20. package/templates/default/.vscode/settings.json +36 -0
  21. package/templates/default/apps/gitkeep +0 -0
  22. package/templates/default/commitlint.config.js +26 -0
  23. package/templates/default/docker/docker-compose.dev.yml +49 -0
  24. package/templates/default/docker/docker-compose.prod.yml +64 -0
  25. package/templates/default/docker/docker-compose.yml +6 -0
  26. package/templates/default/docs/architecture.md +452 -0
  27. package/templates/default/docs/cli.md +330 -0
  28. package/templates/default/docs/contributing.md +462 -0
  29. package/templates/default/docs/scripts.md +460 -0
  30. package/templates/default/gitignore +44 -0
  31. package/templates/default/lintstagedrc.cjs +4 -0
  32. package/templates/default/package.json +51 -0
  33. package/templates/default/packages/auth/package.json +61 -0
  34. package/templates/default/packages/auth/src/components/ProtectedRoute.tsx +75 -0
  35. package/templates/default/packages/auth/src/components/SignInForm.tsx +153 -0
  36. package/templates/default/packages/auth/src/components/SignUpForm.tsx +179 -0
  37. package/templates/default/packages/auth/src/components/SocialButtons.tsx +147 -0
  38. package/templates/default/packages/auth/src/components/index.ts +4 -0
  39. package/templates/default/packages/auth/src/hooks/index.ts +4 -0
  40. package/templates/default/packages/auth/src/hooks/useAuth.ts +51 -0
  41. package/templates/default/packages/auth/src/hooks/useRequireAuth.ts +54 -0
  42. package/templates/default/packages/auth/src/hooks/useSession.ts +48 -0
  43. package/templates/default/packages/auth/src/hooks/useUser.ts +48 -0
  44. package/templates/default/packages/auth/src/index.ts +45 -0
  45. package/templates/default/packages/auth/src/next/index.ts +18 -0
  46. package/templates/default/packages/auth/src/next/middleware.ts +183 -0
  47. package/templates/default/packages/auth/src/next/server.ts +219 -0
  48. package/templates/default/packages/auth/src/providers/AuthContext.tsx +435 -0
  49. package/templates/default/packages/auth/src/providers/index.ts +1 -0
  50. package/templates/default/packages/auth/src/types/index.ts +284 -0
  51. package/templates/default/packages/auth/src/utils/api.ts +228 -0
  52. package/templates/default/packages/auth/src/utils/index.ts +3 -0
  53. package/templates/default/packages/auth/src/utils/oauth.ts +230 -0
  54. package/templates/default/packages/auth/src/utils/token.ts +204 -0
  55. package/templates/default/packages/auth/tsconfig.json +14 -0
  56. package/templates/default/packages/auth/tsup.config.ts +18 -0
  57. package/templates/default/packages/cache/package.json +26 -0
  58. package/templates/default/packages/cache/src/index.ts +137 -0
  59. package/templates/default/packages/cache/tsconfig.json +9 -0
  60. package/templates/default/packages/cache/tsup.config.ts +9 -0
  61. package/templates/default/packages/config/eslint/index.js +20 -0
  62. package/templates/default/packages/config/package.json +9 -0
  63. package/templates/default/packages/config/typescript/base.json +26 -0
  64. package/templates/default/packages/constants/package.json +26 -0
  65. package/templates/default/packages/constants/src/index.ts +121 -0
  66. package/templates/default/packages/constants/tsconfig.json +9 -0
  67. package/templates/default/packages/constants/tsup.config.ts +9 -0
  68. package/templates/default/packages/logger/package.json +27 -0
  69. package/templates/default/packages/logger/src/index.ts +197 -0
  70. package/templates/default/packages/logger/tsconfig.json +11 -0
  71. package/templates/default/packages/logger/tsup.config.ts +9 -0
  72. package/templates/default/packages/result/package.json +26 -0
  73. package/templates/default/packages/result/src/index.ts +142 -0
  74. package/templates/default/packages/result/tsconfig.json +9 -0
  75. package/templates/default/packages/result/tsup.config.ts +9 -0
  76. package/templates/default/packages/types/package.json +26 -0
  77. package/templates/default/packages/types/src/index.ts +78 -0
  78. package/templates/default/packages/types/tsconfig.json +9 -0
  79. package/templates/default/packages/types/tsup.config.ts +10 -0
  80. package/templates/default/packages/ui/package.json +38 -0
  81. package/templates/default/packages/ui/src/components/Button.tsx +58 -0
  82. package/templates/default/packages/ui/src/components/Card.tsx +85 -0
  83. package/templates/default/packages/ui/src/components/Input.tsx +45 -0
  84. package/templates/default/packages/ui/src/index.ts +15 -0
  85. package/templates/default/packages/ui/tsconfig.json +11 -0
  86. package/templates/default/packages/ui/tsup.config.ts +11 -0
  87. package/templates/default/packages/utils/package.json +30 -0
  88. package/templates/default/packages/utils/src/index.test.ts +130 -0
  89. package/templates/default/packages/utils/src/index.ts +154 -0
  90. package/templates/default/packages/utils/tsconfig.json +10 -0
  91. package/templates/default/packages/utils/tsup.config.ts +10 -0
  92. package/templates/default/pnpm-workspace.yaml +3 -0
  93. package/templates/default/scripts/audit.mjs +700 -0
  94. package/templates/default/scripts/deploy.mjs +40 -0
  95. package/templates/default/scripts/generate-app.mjs +808 -0
  96. package/templates/default/scripts/lib/package-manager.mjs +186 -0
  97. package/templates/default/scripts/setup.mjs +102 -0
  98. package/templates/default/services/.env.example +16 -0
  99. package/templates/default/services/docker-compose.yml +207 -0
  100. package/templates/default/services/grafana/provisioning/dashboards/dashboards.yml +11 -0
  101. package/templates/default/services/grafana/provisioning/datasources/datasources.yml +9 -0
  102. package/templates/default/services/postgres/init/gitkeep +2 -0
  103. package/templates/default/services/prometheus/prometheus.yml +13 -0
  104. package/templates/default/tsconfig.json +27 -0
  105. package/templates/default/turbo.json +40 -0
  106. package/templates/default/vitest.config.ts +15 -0
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Package manager detection and utilities
3
+ * Supports: npm, yarn, pnpm
4
+ */
5
+
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import { execSync, spawnSync } from 'child_process';
9
+
10
+ /**
11
+ * Detect which package manager is being used in a project
12
+ * @param {string} projectDir - The project directory to check
13
+ * @returns {'pnpm' | 'yarn' | 'npm'} The detected package manager
14
+ */
15
+ export function detectPackageManager(projectDir = process.cwd()) {
16
+ // Check for lock files
17
+ if (fs.existsSync(path.join(projectDir, 'pnpm-lock.yaml'))) {
18
+ return 'pnpm';
19
+ }
20
+ if (fs.existsSync(path.join(projectDir, 'yarn.lock'))) {
21
+ return 'yarn';
22
+ }
23
+ if (fs.existsSync(path.join(projectDir, 'package-lock.json'))) {
24
+ return 'npm';
25
+ }
26
+
27
+ // Check packageManager field in package.json
28
+ const packageJsonPath = path.join(projectDir, 'package.json');
29
+ if (fs.existsSync(packageJsonPath)) {
30
+ try {
31
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
32
+ if (pkg.packageManager) {
33
+ if (pkg.packageManager.startsWith('pnpm')) return 'pnpm';
34
+ if (pkg.packageManager.startsWith('yarn')) return 'yarn';
35
+ if (pkg.packageManager.startsWith('npm')) return 'npm';
36
+ }
37
+ } catch {
38
+ // Ignore parse errors
39
+ }
40
+ }
41
+
42
+ // Check npm_config_user_agent environment variable (set by package managers)
43
+ const userAgent = process.env.npm_config_user_agent || '';
44
+ if (userAgent.includes('pnpm')) return 'pnpm';
45
+ if (userAgent.includes('yarn')) return 'yarn';
46
+
47
+ // Default to npm
48
+ return 'npm';
49
+ }
50
+
51
+ /**
52
+ * Check if a package manager is installed
53
+ * @param {string} pm - Package manager name
54
+ * @returns {boolean}
55
+ */
56
+ export function isPackageManagerInstalled(pm) {
57
+ try {
58
+ const result = spawnSync(process.platform === 'win32' ? 'where' : 'which', [pm], {
59
+ stdio: 'pipe',
60
+ });
61
+ return result.status === 0;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Get the run command for a package manager
69
+ * @param {'pnpm' | 'yarn' | 'npm'} pm
70
+ * @returns {string}
71
+ */
72
+ export function getRunCommand(pm) {
73
+ switch (pm) {
74
+ case 'pnpm':
75
+ return 'pnpm';
76
+ case 'yarn':
77
+ return 'yarn';
78
+ case 'npm':
79
+ default:
80
+ return 'npm run';
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Get the execute command (for running binaries)
86
+ * @param {'pnpm' | 'yarn' | 'npm'} pm
87
+ * @returns {string}
88
+ */
89
+ export function getExecCommand(pm) {
90
+ switch (pm) {
91
+ case 'pnpm':
92
+ return 'pnpm exec';
93
+ case 'yarn':
94
+ return 'yarn';
95
+ case 'npm':
96
+ default:
97
+ return 'npx';
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Get the install command
103
+ * @param {'pnpm' | 'yarn' | 'npm'} pm
104
+ * @param {object} options
105
+ * @param {boolean} options.frozen - Use frozen lockfile
106
+ * @returns {string}
107
+ */
108
+ export function getInstallCommand(pm, options = {}) {
109
+ const { frozen = false } = options;
110
+
111
+ switch (pm) {
112
+ case 'pnpm':
113
+ return frozen ? 'pnpm install --frozen-lockfile' : 'pnpm install';
114
+ case 'yarn':
115
+ return frozen ? 'yarn install --frozen-lockfile' : 'yarn install';
116
+ case 'npm':
117
+ default:
118
+ return frozen ? 'npm ci' : 'npm install';
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Get the add dependency command
124
+ * @param {'pnpm' | 'yarn' | 'npm'} pm
125
+ * @param {string} pkg - Package name
126
+ * @param {object} options
127
+ * @param {boolean} options.dev - Install as dev dependency
128
+ * @returns {string}
129
+ */
130
+ export function getAddCommand(pm, pkg, options = {}) {
131
+ const { dev = false } = options;
132
+
133
+ switch (pm) {
134
+ case 'pnpm':
135
+ return dev ? `pnpm add -D ${pkg}` : `pnpm add ${pkg}`;
136
+ case 'yarn':
137
+ return dev ? `yarn add -D ${pkg}` : `yarn add ${pkg}`;
138
+ case 'npm':
139
+ default:
140
+ return dev ? `npm install -D ${pkg}` : `npm install ${pkg}`;
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Get workspace filter command
146
+ * @param {'pnpm' | 'yarn' | 'npm'} pm
147
+ * @param {string} workspace - Workspace name
148
+ * @returns {string}
149
+ */
150
+ export function getWorkspaceFilter(pm, workspace) {
151
+ switch (pm) {
152
+ case 'pnpm':
153
+ return `--filter=${workspace}`;
154
+ case 'yarn':
155
+ return `workspace ${workspace}`;
156
+ case 'npm':
157
+ default:
158
+ return `-w ${workspace}`;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Run a command with the detected package manager
164
+ * @param {string} script - Script to run
165
+ * @param {object} options
166
+ * @param {string} options.cwd - Working directory
167
+ * @param {'pnpm' | 'yarn' | 'npm'} options.pm - Package manager (auto-detected if not provided)
168
+ */
169
+ export function runScript(script, options = {}) {
170
+ const { cwd = process.cwd(), pm = detectPackageManager(cwd) } = options;
171
+ const runCmd = getRunCommand(pm);
172
+ const cmd = `${runCmd} ${script}`;
173
+ console.log(`> ${cmd}`);
174
+ execSync(cmd, { stdio: 'inherit', cwd });
175
+ }
176
+
177
+ export default {
178
+ detectPackageManager,
179
+ isPackageManagerInstalled,
180
+ getRunCommand,
181
+ getExecCommand,
182
+ getInstallCommand,
183
+ getAddCommand,
184
+ getWorkspaceFilter,
185
+ runScript,
186
+ };
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { execSync } from 'child_process';
6
+ import { fileURLToPath } from 'url';
7
+ import {
8
+ detectPackageManager,
9
+ isPackageManagerInstalled,
10
+ getInstallCommand,
11
+ getRunCommand,
12
+ } from './lib/package-manager.mjs';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+ const ROOT_DIR = path.resolve(__dirname, '..');
17
+
18
+ // Detect package manager
19
+ const pm = detectPackageManager(ROOT_DIR);
20
+ const runCmd = getRunCommand(pm);
21
+
22
+ console.log('🚀 Setting up monorepo...');
23
+ console.log(`📦 Using package manager: ${pm}`);
24
+
25
+ function run(cmd) {
26
+ console.log(`> ${cmd}`);
27
+ execSync(cmd, { stdio: 'inherit', cwd: ROOT_DIR });
28
+ }
29
+
30
+ // Check if package manager is installed
31
+ if (!isPackageManagerInstalled(pm)) {
32
+ console.log(`📦 Installing ${pm}...`);
33
+ if (pm === 'pnpm') {
34
+ run('npm install -g pnpm');
35
+ } else if (pm === 'yarn') {
36
+ run('npm install -g yarn');
37
+ }
38
+ }
39
+
40
+ // Install dependencies
41
+ console.log('📦 Installing dependencies...');
42
+ run(getInstallCommand(pm));
43
+
44
+ // Setup husky
45
+ console.log('🐶 Setting up Husky...');
46
+ run(`${runCmd} prepare`);
47
+
48
+ // Create environment files
49
+ console.log('🔐 Creating environment files...');
50
+
51
+ const envPath = path.join(ROOT_DIR, '.env');
52
+ if (!fs.existsSync(envPath)) {
53
+ const envContent = `# Database
54
+ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nexu
55
+ DB_USER=postgres
56
+ DB_PASSWORD=postgres
57
+ DB_NAME=nexu
58
+
59
+ # API
60
+ API_URL=http://localhost:4000
61
+
62
+ # App
63
+ NODE_ENV=development
64
+ `;
65
+ fs.writeFileSync(envPath, envContent);
66
+ console.log('✅ Created .env file');
67
+ }
68
+
69
+ const webEnvPath = path.join(ROOT_DIR, 'apps', 'web', '.env.local');
70
+ const webAppsDir = path.join(ROOT_DIR, 'apps', 'web');
71
+ if (fs.existsSync(webAppsDir) && !fs.existsSync(webEnvPath)) {
72
+ const webEnvContent = `NEXT_PUBLIC_API_URL=http://localhost:4000
73
+ `;
74
+ fs.writeFileSync(webEnvPath, webEnvContent);
75
+ console.log('✅ Created apps/web/.env.local');
76
+ }
77
+
78
+ const apiEnvPath = path.join(ROOT_DIR, 'apps', 'api', '.env');
79
+ const apiAppsDir = path.join(ROOT_DIR, 'apps', 'api');
80
+ if (fs.existsSync(apiAppsDir) && !fs.existsSync(apiEnvPath)) {
81
+ const apiEnvContent = `DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nexu
82
+ PORT=4000
83
+ NODE_ENV=development
84
+ `;
85
+ fs.writeFileSync(apiEnvPath, apiEnvContent);
86
+ console.log('✅ Created apps/api/.env');
87
+ }
88
+
89
+ // Build packages
90
+ console.log('🔨 Building packages...');
91
+ run(`${runCmd} build`);
92
+
93
+ console.log('');
94
+ console.log('✅ Setup complete!');
95
+ console.log('');
96
+ console.log('Available commands:');
97
+ console.log(` ${runCmd} dev - Start development servers`);
98
+ console.log(` ${runCmd} build - Build all packages`);
99
+ console.log(` ${runCmd} lint - Run linting`);
100
+ console.log(` ${runCmd} test - Run tests`);
101
+ console.log(` ${runCmd} docker:dev - Start with Docker (dev)`);
102
+ console.log('');
@@ -0,0 +1,16 @@
1
+ # Database
2
+ POSTGRES_USER=nexu
3
+ POSTGRES_PASSWORD=nexu
4
+ POSTGRES_DB=nexu
5
+
6
+ # Messaging
7
+ RABBITMQ_USER=nexu
8
+ RABBITMQ_PASSWORD=nexu
9
+
10
+ # Monitoring
11
+ GRAFANA_USER=admin
12
+ GRAFANA_PASSWORD=admin
13
+
14
+ # Storage
15
+ MINIO_USER=nexu
16
+ MINIO_PASSWORD=nexu1234
@@ -0,0 +1,207 @@
1
+ version: '3.8'
2
+
3
+ # Base docker-compose for external services
4
+ # Usage: docker compose -f services/docker-compose.yml --profile <profile> up -d
5
+ #
6
+ # Available profiles:
7
+ # - database: PostgreSQL, Redis
8
+ # - messaging: RabbitMQ, Kafka
9
+ # - monitoring: Prometheus, Grafana
10
+ # - storage: MinIO (S3-compatible)
11
+ # - search: Elasticsearch
12
+ # - all: All services
13
+
14
+ networks:
15
+ nexu-network:
16
+ driver: bridge
17
+
18
+ volumes:
19
+ postgres_data:
20
+ redis_data:
21
+ rabbitmq_data:
22
+ kafka_data:
23
+ zookeeper_data:
24
+ prometheus_data:
25
+ grafana_data:
26
+ minio_data:
27
+ elasticsearch_data:
28
+
29
+ services:
30
+ # ============================================
31
+ # DATABASE SERVICES
32
+ # ============================================
33
+ postgres:
34
+ image: postgres:16-alpine
35
+ container_name: nexu-postgres
36
+ profiles: ['database', 'all']
37
+ environment:
38
+ POSTGRES_USER: ${POSTGRES_USER:-nexu}
39
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-nexu}
40
+ POSTGRES_DB: ${POSTGRES_DB:-nexu}
41
+ ports:
42
+ - '5432:5432'
43
+ volumes:
44
+ - postgres_data:/var/lib/postgresql/data
45
+ - ./postgres/init:/docker-entrypoint-initdb.d
46
+ networks:
47
+ - nexu-network
48
+ healthcheck:
49
+ test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-nexu}']
50
+ interval: 10s
51
+ timeout: 5s
52
+ retries: 5
53
+
54
+ redis:
55
+ image: redis:7-alpine
56
+ container_name: nexu-redis
57
+ profiles: ['database', 'all']
58
+ command: redis-server --appendonly yes
59
+ ports:
60
+ - '6379:6379'
61
+ volumes:
62
+ - redis_data:/data
63
+ networks:
64
+ - nexu-network
65
+ healthcheck:
66
+ test: ['CMD', 'redis-cli', 'ping']
67
+ interval: 10s
68
+ timeout: 5s
69
+ retries: 5
70
+
71
+ # ============================================
72
+ # MESSAGING SERVICES
73
+ # ============================================
74
+ rabbitmq:
75
+ image: rabbitmq:3-management-alpine
76
+ container_name: nexu-rabbitmq
77
+ profiles: ['messaging', 'all']
78
+ environment:
79
+ RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-nexu}
80
+ RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-nexu}
81
+ ports:
82
+ - '5672:5672'
83
+ - '15672:15672'
84
+ volumes:
85
+ - rabbitmq_data:/var/lib/rabbitmq
86
+ networks:
87
+ - nexu-network
88
+ healthcheck:
89
+ test: ['CMD', 'rabbitmq-diagnostics', '-q', 'ping']
90
+ interval: 30s
91
+ timeout: 10s
92
+ retries: 5
93
+
94
+ zookeeper:
95
+ image: confluentinc/cp-zookeeper:7.5.0
96
+ container_name: nexu-zookeeper
97
+ profiles: ['messaging', 'all']
98
+ environment:
99
+ ZOOKEEPER_CLIENT_PORT: 2181
100
+ ZOOKEEPER_TICK_TIME: 2000
101
+ ports:
102
+ - '2181:2181'
103
+ volumes:
104
+ - zookeeper_data:/var/lib/zookeeper/data
105
+ networks:
106
+ - nexu-network
107
+
108
+ kafka:
109
+ image: confluentinc/cp-kafka:7.5.0
110
+ container_name: nexu-kafka
111
+ profiles: ['messaging', 'all']
112
+ depends_on:
113
+ - zookeeper
114
+ environment:
115
+ KAFKA_BROKER_ID: 1
116
+ KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
117
+ KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
118
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
119
+ ports:
120
+ - '9092:9092'
121
+ volumes:
122
+ - kafka_data:/var/lib/kafka/data
123
+ networks:
124
+ - nexu-network
125
+
126
+ # ============================================
127
+ # MONITORING SERVICES
128
+ # ============================================
129
+ prometheus:
130
+ image: prom/prometheus:latest
131
+ container_name: nexu-prometheus
132
+ profiles: ['monitoring', 'all']
133
+ command:
134
+ - '--config.file=/etc/prometheus/prometheus.yml'
135
+ - '--storage.tsdb.path=/prometheus'
136
+ ports:
137
+ - '9090:9090'
138
+ volumes:
139
+ - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
140
+ - prometheus_data:/prometheus
141
+ networks:
142
+ - nexu-network
143
+
144
+ grafana:
145
+ image: grafana/grafana:latest
146
+ container_name: nexu-grafana
147
+ profiles: ['monitoring', 'all']
148
+ environment:
149
+ GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}
150
+ GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}
151
+ ports:
152
+ - '3001:3000'
153
+ volumes:
154
+ - grafana_data:/var/lib/grafana
155
+ - ./grafana/provisioning:/etc/grafana/provisioning
156
+ networks:
157
+ - nexu-network
158
+ depends_on:
159
+ - prometheus
160
+
161
+ # ============================================
162
+ # STORAGE SERVICES
163
+ # ============================================
164
+ minio:
165
+ image: minio/minio:latest
166
+ container_name: nexu-minio
167
+ profiles: ['storage', 'all']
168
+ command: server /data --console-address ":9001"
169
+ environment:
170
+ MINIO_ROOT_USER: ${MINIO_USER:-nexu}
171
+ MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-nexu1234}
172
+ ports:
173
+ - '9000:9000'
174
+ - '9001:9001'
175
+ volumes:
176
+ - minio_data:/data
177
+ networks:
178
+ - nexu-network
179
+ healthcheck:
180
+ test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
181
+ interval: 30s
182
+ timeout: 20s
183
+ retries: 3
184
+
185
+ # ============================================
186
+ # SEARCH SERVICES
187
+ # ============================================
188
+ elasticsearch:
189
+ image: elasticsearch:8.11.0
190
+ container_name: nexu-elasticsearch
191
+ profiles: ['search', 'all']
192
+ environment:
193
+ - discovery.type=single-node
194
+ - xpack.security.enabled=false
195
+ - 'ES_JAVA_OPTS=-Xms512m -Xmx512m'
196
+ ports:
197
+ - '9200:9200'
198
+ - '9300:9300'
199
+ volumes:
200
+ - elasticsearch_data:/usr/share/elasticsearch/data
201
+ networks:
202
+ - nexu-network
203
+ healthcheck:
204
+ test: ['CMD-SHELL', 'curl -s http://localhost:9200 | grep -q "cluster_name"']
205
+ interval: 30s
206
+ timeout: 10s
207
+ retries: 5
@@ -0,0 +1,11 @@
1
+ apiVersion: 1
2
+
3
+ providers:
4
+ - name: 'default'
5
+ orgId: 1
6
+ folder: ''
7
+ type: file
8
+ disableDeletion: false
9
+ editable: true
10
+ options:
11
+ path: /etc/grafana/provisioning/dashboards
@@ -0,0 +1,9 @@
1
+ apiVersion: 1
2
+
3
+ datasources:
4
+ - name: Prometheus
5
+ type: prometheus
6
+ access: proxy
7
+ url: http://prometheus:9090
8
+ isDefault: true
9
+ editable: false
@@ -0,0 +1,2 @@
1
+ # Place your SQL initialization scripts here
2
+ # They will be executed in alphabetical order when the container starts
@@ -0,0 +1,13 @@
1
+ global:
2
+ scrape_interval: 15s
3
+ evaluation_interval: 15s
4
+
5
+ scrape_configs:
6
+ - job_name: 'prometheus'
7
+ static_configs:
8
+ - targets: ['localhost:9090']
9
+
10
+ # Add your app targets here
11
+ # - job_name: 'nexu-api'
12
+ # static_configs:
13
+ # - targets: ['host.docker.internal:3000']
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "jsx": "react-jsx",
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "resolveJsonModule": true,
9
+ "allowJs": false,
10
+ "declaration": true,
11
+ "declarationMap": true,
12
+ "sourceMap": true,
13
+ "noEmit": true,
14
+ "strict": true,
15
+ "noImplicitAny": true,
16
+ "strictNullChecks": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "esModuleInterop": true,
21
+ "allowSyntheticDefaultImports": true,
22
+ "forceConsistentCasingInFileNames": true,
23
+ "skipLibCheck": true,
24
+ "isolatedModules": true
25
+ },
26
+ "exclude": ["node_modules", "dist", ".next", "coverage", "packages/config", "scripts"]
27
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "globalDependencies": ["**/.env.*local"],
4
+ "globalEnv": ["NODE_ENV"],
5
+ "remoteCache": {
6
+ "signature": true
7
+ },
8
+ "tasks": {
9
+ "build": {
10
+ "dependsOn": ["^build"],
11
+ "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
12
+ },
13
+ "dev": {
14
+ "cache": false,
15
+ "persistent": true
16
+ },
17
+ "lint": {
18
+ "dependsOn": ["^build"],
19
+ "outputs": []
20
+ },
21
+ "lint:fix": {
22
+ "outputs": []
23
+ },
24
+ "test": {
25
+ "dependsOn": ["build"],
26
+ "outputs": ["coverage/**"]
27
+ },
28
+ "test:coverage": {
29
+ "dependsOn": ["build"],
30
+ "outputs": ["coverage/**"]
31
+ },
32
+ "typecheck": {
33
+ "dependsOn": ["^build"],
34
+ "outputs": []
35
+ },
36
+ "clean": {
37
+ "cache": false
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ include: ['**/*.{test,spec}.{ts,tsx}'],
8
+ exclude: ['**/node_modules/**', '**/dist/**'],
9
+ coverage: {
10
+ provider: 'v8',
11
+ reporter: ['text', 'json', 'html'],
12
+ exclude: ['node_modules/', 'dist/', '**/*.config.*', '**/*.d.ts', '**/types/'],
13
+ },
14
+ },
15
+ });