@ecopex/ecopex-framework 1.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 (81) hide show
  1. package/.env +73 -0
  2. package/README.md +248 -0
  3. package/bun.lockb +0 -0
  4. package/config/swagger/admin.js +44 -0
  5. package/config/swagger/api.js +19 -0
  6. package/database/migrations/20240000135243_timezones.js +22 -0
  7. package/database/migrations/20240000135244_countries.js +23 -0
  8. package/database/migrations/20240000135244_create_admins_table.js +66 -0
  9. package/database/migrations/20240000135244_currencies.js +21 -0
  10. package/database/migrations/20240000135244_languages.js +21 -0
  11. package/database/migrations/20240000135244_taxes.js +10 -0
  12. package/database/migrations/20240000135245_sites.js +37 -0
  13. package/database/migrations/20240000135246_payment_methods.js +33 -0
  14. package/database/migrations/20251016113547_devices.js +37 -0
  15. package/database/migrations/20251019192600_users.js +62 -0
  16. package/database/migrations/20251019213551_language_lines.js +35 -0
  17. package/database/migrations/20251222214131_category_groups.js +18 -0
  18. package/database/migrations/20251222214619_categories.js +27 -0
  19. package/database/migrations/20251222214848_brands.js +23 -0
  20. package/database/migrations/20251222214946_products.js +30 -0
  21. package/database/migrations/20251222215428_product_images.js +18 -0
  22. package/database/migrations/20251222215553_options.js +30 -0
  23. package/database/migrations/20251222215806_variants.js +23 -0
  24. package/database/migrations/20251222215940_attributes.js +25 -0
  25. package/database/migrations/20251222220135_discounts.js +15 -0
  26. package/database/migrations/20251222220253_reviews.js +22 -0
  27. package/database/migrations/20251222220341_favorites.js +10 -0
  28. package/database/migrations/20251222220422_search_logs.js +17 -0
  29. package/database/migrations/20251222220636_orders.js +16 -0
  30. package/database/migrations/20251222220806_order_items.js +19 -0
  31. package/database/migrations/20251222221317_order_statuses.js +10 -0
  32. package/database/migrations/20251222221446_order_payments.js +13 -0
  33. package/database/migrations/20251222221654_order_addresses.js +23 -0
  34. package/database/migrations/20251222221807_order_status_logs.js +13 -0
  35. package/database/seeds/admins.js +37 -0
  36. package/database/seeds/countries.js +203 -0
  37. package/database/seeds/currencies.js +165 -0
  38. package/database/seeds/languages.js +113 -0
  39. package/database/seeds/timezones.js +149 -0
  40. package/ecosystem.config.js +26 -0
  41. package/env.example +73 -0
  42. package/knexfile.js +3 -0
  43. package/libraries/2fa.js +22 -0
  44. package/libraries/aws.js +63 -0
  45. package/libraries/bcrypt.js +284 -0
  46. package/libraries/controls.js +113 -0
  47. package/libraries/date.js +14 -0
  48. package/libraries/general.js +8 -0
  49. package/libraries/image.js +57 -0
  50. package/libraries/jwt.js +178 -0
  51. package/libraries/knex.js +7 -0
  52. package/libraries/slug.js +14 -0
  53. package/libraries/stores.js +22 -0
  54. package/libraries/upload.js +194 -0
  55. package/locales/en/messages.json +4 -0
  56. package/locales/en/sql.json +3 -0
  57. package/locales/en/validation.json +52 -0
  58. package/locales/es/validation.json +52 -0
  59. package/locales/tr/validation.json +59 -0
  60. package/package.json +75 -0
  61. package/routes/admin/auto/admins.json +63 -0
  62. package/routes/admin/auto/devices.json +37 -0
  63. package/routes/admin/auto/migrations.json +21 -0
  64. package/routes/admin/auto/users.json +61 -0
  65. package/routes/admin/middlewares/index.js +87 -0
  66. package/routes/admin/spec/auth.js +626 -0
  67. package/routes/admin/spec/users.js +3 -0
  68. package/routes/auto/handler.js +635 -0
  69. package/routes/common/auto/countries.json +28 -0
  70. package/routes/common/auto/currencies.json +26 -0
  71. package/routes/common/auto/languages.json +26 -0
  72. package/routes/common/auto/taxes.json +46 -0
  73. package/routes/common/auto/timezones.json +29 -0
  74. package/stores/base.js +73 -0
  75. package/stores/index.js +195 -0
  76. package/utils/i18n.js +187 -0
  77. package/utils/jsonRouteLoader.js +587 -0
  78. package/utils/middleware.js +154 -0
  79. package/utils/routeLoader.js +227 -0
  80. package/workers/admin.js +124 -0
  81. package/workers/api.js +106 -0
package/.env ADDED
@@ -0,0 +1,73 @@
1
+ # ===========================================
2
+ # SB System Environment Configuration
3
+ # ===========================================
4
+
5
+ # Application Environment
6
+ NODE_ENV=development
7
+ LOG_LEVEL=error
8
+
9
+ # Server Configuration
10
+ HOST=0.0.0.0
11
+ API_PORT=3000
12
+ ADMIN_PORT=3001
13
+
14
+ # Database Configuration
15
+ DB_HOST=127.0.0.1
16
+ DB_PORT=3306
17
+ DB_USER=root
18
+ DB_PASSWORD=Gs1905ua
19
+ DB_NAME=ecommerce
20
+
21
+ # Alternative: Use DATABASE_URL for production
22
+ # DATABASE_URL=mysql://username:password@host:port/database
23
+
24
+ # CORS Configuration
25
+ CORS_ORIGIN=*
26
+
27
+ # PM2 Process Management
28
+ API_INSTANCES=1
29
+ API_EXEC_MODE=fork
30
+ ADMIN_INSTANCES=1
31
+ ADMIN_EXEC_MODE=fork
32
+
33
+ # Internationalization
34
+ DEFAULT_LOCALE=en
35
+ SUPPORTED_LOCALES=en,tr,es
36
+
37
+ # Security (for production)
38
+ # JWT_SECRET=your_jwt_secret_here
39
+ # BCRYPT_ROUNDS=12
40
+ # SESSION_SECRET=your_session_secret_here
41
+
42
+ # Redis (for caching/sessions)
43
+ # REDIS_HOST=localhost
44
+ # REDIS_PORT=6379
45
+ # REDIS_PASSWORD=
46
+
47
+ # Email Configuration (for notifications)
48
+ # SMTP_HOST=smtp.gmail.com
49
+ # SMTP_PORT=587
50
+ # SMTP_USER=your_email@gmail.com
51
+ # SMTP_PASS=your_app_password
52
+ # FROM_EMAIL=noreply@yoursystem.com
53
+
54
+ # File Upload Configuration
55
+ # UPLOAD_MAX_SIZE=10485760
56
+ # UPLOAD_ALLOWED_TYPES=image/jpeg,image/png,image/gif,application/pdf
57
+
58
+ # Rate Limiting
59
+ # RATE_LIMIT_WINDOW_MS=900000
60
+ # RATE_LIMIT_MAX_REQUESTS=100
61
+
62
+ # Logging
63
+ # LOG_FILE_PATH=./logs/app.log
64
+ # LOG_MAX_SIZE=10m
65
+ # LOG_MAX_FILES=5
66
+
67
+ # Monitoring
68
+ # HEALTH_CHECK_INTERVAL=30000
69
+ # METRICS_ENABLED=true
70
+
71
+ # Development Tools
72
+ # DEBUG=sb_system:*
73
+ # NODE_OPTIONS=--max-old-space-size=4096
package/README.md ADDED
@@ -0,0 +1,248 @@
1
+ # SB System
2
+
3
+ A Node.js system built with Fastify, Knex, and Ajv for automatic routing and database management with PM2 process management.
4
+
5
+ ## Features
6
+
7
+ - **Fastify**: High-performance web framework
8
+ - **Knex**: SQL query builder with migrations and seeds
9
+ - **Ajv**: JSON schema validation
10
+ - **MySQL**: Database support
11
+ - **PM2**: Process management for production
12
+ - **Microservices**: Separate admin and API services
13
+ - **Automatic Routing**: Dynamic route loading from directory structure
14
+
15
+ ## Project Structure
16
+
17
+ ```
18
+ sb_system/
19
+ ├── workers/
20
+ │ ├── admin.js # Admin service worker
21
+ │ └── api.js # API service worker
22
+ ├── routes/
23
+ │ ├── admin/
24
+ │ │ └── users/
25
+ │ │ ├── route.js # Route definitions
26
+ │ │ ├── handler.js # Route handlers
27
+ │ │ └── validation.js # Validation schemas
28
+ │ └── api/
29
+ ├── database/
30
+ │ ├── migrations/
31
+ │ └── seeds/
32
+ ├── config/
33
+ │ └── database.js
34
+ ├── utils/
35
+ │ ├── routeLoader.js
36
+ │ └── validator.js
37
+ ├── logs/ # PM2 log files
38
+ ├── ecosystem.config.js # PM2 configuration
39
+ └── package.json
40
+ ```
41
+
42
+ ## Installation
43
+
44
+ 1. Install dependencies:
45
+ ```bash
46
+ npm install
47
+ ```
48
+
49
+ 2. Set up environment variables:
50
+ ```bash
51
+ # Copy the example and configure your settings
52
+ cp env.example .env
53
+ ```
54
+
55
+ 3. Configure your environment in `.env`:
56
+ ```bash
57
+ # Database Configuration
58
+ DB_HOST=localhost
59
+ DB_PORT=3306
60
+ DB_USER=your_username
61
+ DB_PASSWORD=your_password
62
+ DB_NAME=sb_system
63
+
64
+ # Server Configuration
65
+ API_PORT=3000
66
+ ADMIN_PORT=3001
67
+ HOST=0.0.0.0
68
+
69
+ # Optional: Internationalization
70
+ DEFAULT_LOCALE=en
71
+ SUPPORTED_LOCALES=en,tr,es
72
+ ```
73
+
74
+ 4. Run database migrations:
75
+ ```bash
76
+ npm run migrate
77
+ ```
78
+
79
+ 5. Seed the database (optional):
80
+ ```bash
81
+ npm run seed
82
+ ```
83
+
84
+ > **Note**: See [ENVIRONMENT.md](./ENVIRONMENT.md) for complete environment variable documentation.
85
+
86
+ ## Usage
87
+
88
+ ### Development
89
+ ```bash
90
+ # Start both services with PM2
91
+ npm run dev
92
+
93
+ # Or start individual services for development
94
+ npm run dev:api # API service only
95
+ npm run dev:admin # Admin service only
96
+ ```
97
+
98
+ ### Production
99
+ ```bash
100
+ # Start all services
101
+ npm start
102
+
103
+ # Or start with production environment
104
+ npm run prod
105
+ ```
106
+
107
+ ### PM2 Management
108
+ ```bash
109
+ # View status
110
+ npm run status
111
+
112
+ # View logs
113
+ npm run logs
114
+
115
+ # Restart services
116
+ npm run restart
117
+
118
+ # Stop services
119
+ npm run stop
120
+
121
+ # Reload services (zero-downtime)
122
+ npm run reload
123
+
124
+ # Delete all services
125
+ npm run delete
126
+ ```
127
+
128
+ ## Services
129
+
130
+ ### API Service (Port 3000)
131
+ - **Health Check**: `GET http://localhost:3000/health`
132
+ - **Documentation**: `GET http://localhost:3000/docs`
133
+ - **Welcome**: `GET http://localhost:3000/`
134
+ - **Language Management**:
135
+ - `GET /api/language` - Get supported languages
136
+ - `POST /api/language/set` - Set preferred language
137
+ - `GET /api/language/detect` - Detect language from headers
138
+
139
+ ### Admin Service (Port 3001)
140
+ - **Health Check**: `GET http://localhost:3001/health`
141
+ - **Documentation**: `GET http://localhost:3001/docs`
142
+ - **User Management**:
143
+ - `GET /admin/users` - Get all users (with pagination)
144
+ - `GET /admin/users/:id` - Get user by ID
145
+ - `POST /admin/users` - Create new user
146
+ - `PUT /admin/users/:id` - Update user
147
+ - `DELETE /admin/users/:id` - Delete user
148
+
149
+ ## Adding New Routes
150
+
151
+ 1. Create a new directory under `routes/admin/` or `routes/api/`
152
+ 2. Add three files:
153
+ - `route.js` - Define your routes
154
+ - `handler.js` - Implement route handlers
155
+ - `validation.js` - Define validation schemas
156
+
157
+ ### Example Route Structure
158
+
159
+ ```javascript
160
+ // routes/admin/products/route.js
161
+ module.exports = [
162
+ {
163
+ method: 'GET',
164
+ url: '',
165
+ handlerName: 'getAllProducts',
166
+ validationName: 'getAllProductsValidation',
167
+ schema: {
168
+ // Fastify schema definition
169
+ }
170
+ }
171
+ ];
172
+
173
+ // routes/admin/products/handler.js
174
+ class ProductHandler {
175
+ static async getAllProducts(request, reply) {
176
+ // Handler implementation
177
+ }
178
+ }
179
+
180
+ module.exports = ProductHandler;
181
+
182
+ // routes/admin/products/validation.js
183
+ module.exports = {
184
+ getAllProductsValidation: {
185
+ // Ajv validation schema
186
+ }
187
+ };
188
+ ```
189
+
190
+ ## Database
191
+
192
+ The system uses Knex.js for database operations with MySQL. Migrations and seeds are included for easy setup.
193
+
194
+ ### Available Commands
195
+ - `npm run migrate` - Run migrations
196
+ - `npm run migrate:rollback` - Rollback migrations
197
+ - `npm run seed` - Run seeds
198
+
199
+ ## Multi-Language Support
200
+
201
+ The system includes comprehensive internationalization (i18n) support with automatic language detection and validation error translation.
202
+
203
+ ### Supported Languages
204
+ - **English (en)** - Default
205
+ - **Turkish (tr)** - Türkçe
206
+ - **Spanish (es)** - Español
207
+
208
+ ### Language Detection
209
+ The system automatically detects language from:
210
+ 1. `Accept-Language` header
211
+ 2. `X-Language` header
212
+ 3. `lang` query parameter
213
+ 4. Falls back to default locale
214
+
215
+ ### Language Endpoints
216
+ ```bash
217
+ # Get supported languages
218
+ GET /api/language
219
+
220
+ # Set preferred language
221
+ POST /api/language/set
222
+ {
223
+ "language": "tr"
224
+ }
225
+
226
+ # Detect language from headers
227
+ GET /api/language/detect
228
+ ```
229
+
230
+ ### Usage Examples
231
+ ```bash
232
+ # Request with Turkish language
233
+ curl -H "Accept-Language: tr" http://localhost:3000/api/language
234
+
235
+ # Request with custom language header
236
+ curl -H "X-Language: es" http://localhost:3000/admin/users
237
+
238
+ # Request with query parameter
239
+ curl "http://localhost:3000/admin/users?lang=tr"
240
+ ```
241
+
242
+ ## Validation
243
+
244
+ The system uses Ajv for JSON schema validation with multi-language error messages. Validation schemas are defined in the `validation.js` files and automatically applied to routes.
245
+
246
+ ## License
247
+
248
+ MIT
package/bun.lockb ADDED
Binary file
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Swagger configuration for Admin service
3
+ */
4
+ module.exports = {
5
+ swagger: {
6
+ openapi: {
7
+ info: {
8
+ title: 'Ecommerce Admin API',
9
+ description: 'Admin API documentation for Ecommerce',
10
+ version: '1.0.0'
11
+ },
12
+ host: `${process.env.HOST || 'localhost'}:${process.env.ADMIN_PORT || 3001}`,
13
+ schemes: ['http', 'https'],
14
+ consumes: ['application/json'],
15
+ produces: ['application/json'],
16
+ components: {
17
+ securitySchemes: {
18
+ bearer: {
19
+ type: 'http',
20
+ scheme: 'bearer',
21
+ bearerFormat: 'JWT',
22
+ description: 'Enter the token with the `Bearer: ` prefix, e.g. "Bearer abcde12345".'
23
+ },
24
+ apiKey: {
25
+ type: 'apiKey',
26
+ in: 'header',
27
+ name: 'apiKey',
28
+ description: 'Enter token e.g. "abcde1-234533-333312-2222".'
29
+ }
30
+ },
31
+ headers: {
32
+ description: 'Headers',
33
+ scheme: {
34
+ type: 'object',
35
+ properties: {}
36
+ }
37
+ }
38
+ }
39
+ }
40
+ },
41
+ swaggerUi: {
42
+ routePrefix: '/docs'
43
+ }
44
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Swagger configuration for API service
3
+ */
4
+ module.exports = {
5
+ swagger: {
6
+ info: {
7
+ title: 'SB System API',
8
+ description: 'API documentation for SB System',
9
+ version: '1.0.0'
10
+ },
11
+ host: `${process.env.HOST || 'localhost'}:${process.env.API_PORT || 3000}`,
12
+ schemes: ['http', 'https'],
13
+ consumes: ['application/json'],
14
+ produces: ['application/json']
15
+ },
16
+ swaggerUi: {
17
+ routePrefix: '/docs'
18
+ }
19
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('timezones', function(table) {
7
+ // Primary key
8
+ table.increments('timezone_id').primary();
9
+ table.string('name', 100).notNullable();
10
+ table.string('code', 100).notNullable();
11
+ table.string('offset', 100).notNullable();
12
+ table.string('gmt', 100).notNullable();
13
+ });
14
+ };
15
+
16
+ /**
17
+ * @param { import("knex").Knex } knex
18
+ * @returns { Promise<void> }
19
+ */
20
+ exports.down = function(knex) {
21
+ return knex.schema.dropTable('timezones');
22
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('countries', function(table) {
7
+ // Primary key
8
+ table.increments('country_id').primary();
9
+ table.string('name', 100).notNullable();
10
+ table.string('code', 100).notNullable();
11
+ table.string('iso_code', 100).notNullable();
12
+ table.string('phone_code', 100).notNullable();
13
+ table.string('flag', 100).notNullable();
14
+ });
15
+ };
16
+
17
+ /**
18
+ * @param { import("knex").Knex } knex
19
+ * @returns { Promise<void> }
20
+ */
21
+ exports.down = function(knex) {
22
+ return knex.schema.dropTable('countries');
23
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('admins', function(table) {
7
+ // Primary key
8
+ table.increments('admin_id').primary();
9
+ table.integer('country_id').unsigned().references('country_id').inTable('countries');
10
+
11
+ // Basic admin information
12
+ table.string('firstname', 100).nullable();
13
+ table.string('lastname', 100).nullable();
14
+ table.string('username', 100).notNullable().unique();
15
+ table.string('email', 255).nullable().unique();
16
+ table.string('password', 255).notNullable();
17
+ table.enum('role', ['admin', 'manager']).defaultTo('manager');
18
+
19
+ // Two-factor authentication fields
20
+ table.boolean('two_factor_enabled').defaultTo(false);
21
+ table.string('two_factor_secret', 32).nullable(); // TOTP secret
22
+ table.string('phone_number', 20).nullable();
23
+ table.boolean('phone_verified').defaultTo(false);
24
+ table.boolean('email_verified').defaultTo(false);
25
+
26
+ // Login security
27
+ table.integer('login_attempts').defaultTo(0);
28
+ table.timestamp('locked_until').nullable();
29
+
30
+ // Password security
31
+ table.timestamp('password_changed_at').nullable();
32
+ table.string('password_reset_token', 255).nullable();
33
+
34
+ // Email verification
35
+ table.string('email_verification_token', 255).nullable();
36
+
37
+ // Phone verification
38
+ table.string('phone_verification_code', 10).nullable();
39
+
40
+ // Address information
41
+ table.string('address', 255).nullable();
42
+ table.string('city', 100).nullable();
43
+ table.string('state', 100).nullable();
44
+ table.string('zip', 20).nullable();
45
+
46
+ // Status and timestamps
47
+ table.boolean('is_active').defaultTo(true);
48
+
49
+ // Audit timestamps
50
+ table.timestamps(true, true); // created_at and updated_at
51
+
52
+ // Indexes for performance
53
+ table.index(['role']);
54
+ table.index(['is_active']);
55
+ table.index(['two_factor_enabled']);
56
+ table.index(['created_at']);
57
+ });
58
+ };
59
+
60
+ /**
61
+ * @param { import("knex").Knex } knex
62
+ * @returns { Promise<void> }
63
+ */
64
+ exports.down = function(knex) {
65
+ return knex.schema.dropTable('admins');
66
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('currencies', function(table) {
7
+ // Primary key
8
+ table.increments('currency_id').primary();
9
+ table.string('name', 100).notNullable();
10
+ table.string('code', 100).notNullable();
11
+ table.string('symbol', 100).notNullable();
12
+ });
13
+ };
14
+
15
+ /**
16
+ * @param { import("knex").Knex } knex
17
+ * @returns { Promise<void> }
18
+ */
19
+ exports.down = function(knex) {
20
+ return knex.schema.dropTable('currencies');
21
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('languages', function(table) {
7
+ // Primary key
8
+ table.increments('language_id').primary();
9
+ table.string('name', 100).notNullable();
10
+ table.string('code', 100).notNullable();
11
+ table.string('flag', 100).notNullable();
12
+ });
13
+ };
14
+
15
+ /**
16
+ * @param { import("knex").Knex } knex
17
+ * @returns { Promise<void> }
18
+ */
19
+ exports.down = function(knex) {
20
+ return knex.schema.dropTable('languages');
21
+ };
@@ -0,0 +1,10 @@
1
+
2
+ exports.up = knex =>
3
+ knex.schema.createTable('taxes', table => {
4
+ table.increments('tax_id').primary();
5
+ table.string('name').notNullable();
6
+ table.decimal('rate', 5, 2).notNullable();
7
+ });
8
+
9
+ exports.down = knex =>
10
+ knex.schema.dropTable('taxes');
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('sites', function(table) {
7
+ table.increments('site_id').primary();
8
+ table.integer('admin_id').unsigned().references('admin_id').inTable('admins');
9
+ table.integer('currency_id').unsigned().references('currency_id').inTable('currencies');
10
+ table.integer('timezone_id').unsigned().references('timezone_id').inTable('timezones');
11
+ table.integer('language_id').unsigned().references('language_id').inTable('languages');
12
+ table.integer('country_id').unsigned().references('country_id').inTable('countries');
13
+ table.integer('tax_id').unsigned().references('tax_id').inTable('taxes');
14
+ table.string('name', 100).notNullable();
15
+ table.string('domain', 100).notNullable().unique();
16
+ table.string('logo', 100).notNullable();
17
+ table.string('favicon', 100).notNullable();
18
+ table.string('description', 100).notNullable();
19
+ table.string('keywords', 100).notNullable();
20
+ table.boolean('is_active').defaultTo(true);
21
+ table.datetime('expires_at').notNullable();
22
+ table.timestamps(true, true);
23
+ table.index(['admin_id'], 'site_admin_id_index');
24
+ table.index(['name'], 'site_name_index');
25
+ table.index(['domain'], 'site_domain_index');
26
+ table.index(['created_at'], 'site_created_at_index');
27
+ table.index(['updated_at'], 'site_updated_at_index');
28
+ });
29
+ };
30
+
31
+ /**
32
+ * @param { import("knex").Knex } knex
33
+ * @returns { Promise<void> }
34
+ */
35
+ exports.down = function(knex) {
36
+ return knex.schema.dropTable('sites');
37
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = knex => knex.schema.createTable('payment_methods', function(table) {
6
+ // Primary key
7
+ table.increments('payment_method_id').primary();
8
+ table.integer('site_id').unsigned().references('site_id').inTable('sites');
9
+ table.integer('currency_id').unsigned().references('currency_id').inTable('currencies');
10
+ table.string('logo').defaultTo(null);
11
+ table.string('name').notNullable();
12
+ table.string('code').unique().notNullable();
13
+ table.string('provider').defaultTo(null);
14
+ table.string('api_key').defaultTo(null);
15
+ table.string('api_secret').defaultTo(null);
16
+ table.string('api_url').defaultTo(null);
17
+ table.string('api_version').defaultTo(null);
18
+ table.boolean('is_active').defaultTo(true);
19
+ table.timestamps(true, true);
20
+ }).createTable('payment_method_translations', table => {
21
+ table.increments('payment_method_translation_id').primary();
22
+ table.integer('payment_method_id').unsigned().references('payment_method_id').inTable('payment_methods').onDelete('CASCADE');
23
+ table.integer('language_id').unsigned().references('language_id').inTable('languages');
24
+ table.string('description').notNullable();
25
+ });
26
+
27
+ /**
28
+ * @param { import("knex").Knex } knex
29
+ * @returns { Promise<void> }
30
+ */
31
+ exports.down = knex =>
32
+ knex.schema.dropTable('payment_method_translations')
33
+ .dropTable('payment_methods');
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @param { import("knex").Knex } knex
3
+ * @returns { Promise<void> }
4
+ */
5
+ exports.up = function(knex) {
6
+ return knex.schema.createTable('devices', function (table) {
7
+ table.increments('device_id').unsigned().notNullable().primary();
8
+ table.integer('personal_id');
9
+ table.enum('personal_type', ['admin', 'site', 'user']).notNullable();
10
+ table.string('unique_id', 100).notNullable();
11
+ table.string('ip_address', 100).notNullable();
12
+ table.text('device_information').notNullable();
13
+ table.boolean('two_factor_approved').defaultTo(false);
14
+ table.string('token', 255).notNullable();
15
+ table.datetime('last_login_at').notNullable();
16
+ table.string('last_login_ip', 100).notNullable();
17
+ table.datetime('created_at').notNullable().defaultTo(knex.fn.now());
18
+ table.datetime('updated_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
19
+ table.unique(['unique_id', 'personal_id', 'personal_type'], 'device_unique_index')
20
+ table.index(['personal_id', 'personal_type'], 'device_personal_index')
21
+ table.index(['token'], 'device_token_index')
22
+ })
23
+ };
24
+
25
+ /**
26
+ * @param { import("knex").Knex } knex
27
+ * @returns { Promise<void> }
28
+ */
29
+ exports.down = async function(knex) {
30
+ if (process.env.NODE_ENV === 'production') {
31
+ throw new Error('Cannot drop table in production environment.')
32
+ } else {
33
+ if(await knex.schema.hasTable('devices')) {
34
+ return knex.schema.dropTable('devices');
35
+ }
36
+ }
37
+ };