@ecopex/ecopex-framework 1.0.0 → 1.0.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 (60) hide show
  1. package/index.js +5 -0
  2. package/libraries/fastify.js +120 -0
  3. package/libraries/knex.js +1 -1
  4. package/package.json +6 -2
  5. package/stores/base.js +1 -1
  6. package/utils/jsonRouteLoader.js +3 -3
  7. package/utils/middleware.js +1 -1
  8. package/utils/routeLoader.js +1 -1
  9. package/.env +0 -73
  10. package/database/migrations/20240000135243_timezones.js +0 -22
  11. package/database/migrations/20240000135244_countries.js +0 -23
  12. package/database/migrations/20240000135244_create_admins_table.js +0 -66
  13. package/database/migrations/20240000135244_currencies.js +0 -21
  14. package/database/migrations/20240000135244_languages.js +0 -21
  15. package/database/migrations/20240000135244_taxes.js +0 -10
  16. package/database/migrations/20240000135245_sites.js +0 -37
  17. package/database/migrations/20240000135246_payment_methods.js +0 -33
  18. package/database/migrations/20251016113547_devices.js +0 -37
  19. package/database/migrations/20251019192600_users.js +0 -62
  20. package/database/migrations/20251019213551_language_lines.js +0 -35
  21. package/database/migrations/20251222214131_category_groups.js +0 -18
  22. package/database/migrations/20251222214619_categories.js +0 -27
  23. package/database/migrations/20251222214848_brands.js +0 -23
  24. package/database/migrations/20251222214946_products.js +0 -30
  25. package/database/migrations/20251222215428_product_images.js +0 -18
  26. package/database/migrations/20251222215553_options.js +0 -30
  27. package/database/migrations/20251222215806_variants.js +0 -23
  28. package/database/migrations/20251222215940_attributes.js +0 -25
  29. package/database/migrations/20251222220135_discounts.js +0 -15
  30. package/database/migrations/20251222220253_reviews.js +0 -22
  31. package/database/migrations/20251222220341_favorites.js +0 -10
  32. package/database/migrations/20251222220422_search_logs.js +0 -17
  33. package/database/migrations/20251222220636_orders.js +0 -16
  34. package/database/migrations/20251222220806_order_items.js +0 -19
  35. package/database/migrations/20251222221317_order_statuses.js +0 -10
  36. package/database/migrations/20251222221446_order_payments.js +0 -13
  37. package/database/migrations/20251222221654_order_addresses.js +0 -23
  38. package/database/migrations/20251222221807_order_status_logs.js +0 -13
  39. package/database/seeds/admins.js +0 -37
  40. package/database/seeds/countries.js +0 -203
  41. package/database/seeds/currencies.js +0 -165
  42. package/database/seeds/languages.js +0 -113
  43. package/database/seeds/timezones.js +0 -149
  44. package/ecosystem.config.js +0 -26
  45. package/libraries/stores.js +0 -22
  46. package/routes/admin/auto/admins.json +0 -63
  47. package/routes/admin/auto/devices.json +0 -37
  48. package/routes/admin/auto/migrations.json +0 -21
  49. package/routes/admin/auto/users.json +0 -61
  50. package/routes/admin/middlewares/index.js +0 -87
  51. package/routes/admin/spec/auth.js +0 -626
  52. package/routes/admin/spec/users.js +0 -3
  53. package/routes/auto/handler.js +0 -635
  54. package/routes/common/auto/countries.json +0 -28
  55. package/routes/common/auto/currencies.json +0 -26
  56. package/routes/common/auto/languages.json +0 -26
  57. package/routes/common/auto/taxes.json +0 -46
  58. package/routes/common/auto/timezones.json +0 -29
  59. package/workers/admin.js +0 -124
  60. package/workers/api.js +0 -106
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ const { start: fastifyStart } = require('./libraries/fastify');
2
+
3
+ module.exports = {
4
+ fastifyStart
5
+ }
@@ -0,0 +1,120 @@
1
+ require('dotenv').config();
2
+
3
+ const fastify = require('fastify')({
4
+ logger: {
5
+ level: process.env.LOG_LEVEL || 'info'
6
+ }
7
+ });
8
+
9
+ const { loadRoutes } = require('@root/utils/routeLoader');
10
+ const Middleware = require('@root/utils/middleware');
11
+
12
+ // Register plugins
13
+ async function registerPlugins() {
14
+ // Set error handler first, before any plugins
15
+ fastify.setErrorHandler(Middleware.errorHandler);
16
+ fastify.setNotFoundHandler(Middleware.errorNotFoundHandler);
17
+
18
+ // CORS plugin
19
+ await fastify.register(require('@fastify/cors'), {
20
+ origin: process.env.CORS_ORIGIN || '*',
21
+ credentials: true
22
+ });
23
+
24
+ // Swagger documentation
25
+ const swaggerConfig = require('@root/config/swagger/admin');
26
+
27
+ await fastify.register(require('@fastify/swagger'), swaggerConfig.swagger);
28
+
29
+ // Swagger UI
30
+ await fastify.register(require('@fastify/swagger-ui'), swaggerConfig.swaggerUi);
31
+
32
+ // Fastify Multipart plugin
33
+ fastify.register(require('@fastify/multipart'), {
34
+ attachFieldsToBody: true, // Optional: attaches fields to the body object
35
+ throwFileSizeLimit: true, // Optional: throws an error if the file size limit is exceeded
36
+ limits: {
37
+ fieldNameSize: 100, // Max field name size in bytes
38
+ fieldSize: 100, // Max field value size in bytes
39
+ fields: 10, // Max number of non-file fields
40
+ fileSize: 1000000, // For multipart forms, the max file size in bytes
41
+ files: 1, // Max number of file fields
42
+ headerPairs: 2000, // Max number of header key=>value pairs
43
+ parts: 1000 // For multipart forms, the max number of parts (fields + files)
44
+ }
45
+ });
46
+
47
+ // Register other middleware
48
+ fastify.addHook('preHandler', Middleware.languageDetection());
49
+ fastify.addHook('preHandler', Middleware.responseFormatter());
50
+
51
+ // Health check endpoint
52
+ fastify.get('/health', async (request, reply) => {
53
+ return {
54
+ status: 'ok',
55
+ service: 'admin',
56
+ timestamp: new Date().toISOString(),
57
+ uptime: process.uptime(),
58
+ pid: process.pid
59
+ };
60
+ });
61
+ }
62
+
63
+ // Load admin routes, common routes, and auto routes
64
+ async function loadAdminRoutes() {
65
+ try {
66
+ // Load admin routes
67
+ await loadRoutes(fastify, __dirname + '/../routes/admin', true, 'admin');
68
+ } catch (error) {
69
+ console.error('Error loading admin routes:', error);
70
+ process.exit(1);
71
+ }
72
+ }
73
+
74
+ // Start admin service
75
+ async function start() {
76
+ try {
77
+
78
+ // Register plugins
79
+ await registerPlugins();
80
+
81
+ // Load admin routes
82
+ await loadAdminRoutes();
83
+
84
+ // Start server
85
+ const port = process.env.PORT || 3001;
86
+ const host = process.env.HOST || '127.0.0.1';
87
+
88
+ fastify.listen({ port, host });
89
+
90
+ } catch (error) {
91
+ console.error('Error starting admin service:', error);
92
+ process.exit(1);
93
+ }
94
+ }
95
+
96
+ // Graceful shutdown
97
+ process.on('SIGINT', async () => {
98
+ try {
99
+ await fastify.close();
100
+ process.exit(0);
101
+ } catch (error) {
102
+ console.error('Error during admin service shutdown:', error);
103
+ process.exit(1);
104
+ }
105
+ });
106
+
107
+ process.on('SIGTERM', async () => {
108
+ try {
109
+ await fastify.close();
110
+ process.exit(0);
111
+ } catch (error) {
112
+ console.error('Error during admin service shutdown:', error);
113
+ process.exit(1);
114
+ }
115
+ });
116
+
117
+ // Start the admin service
118
+ module.exports = {
119
+ start
120
+ }
package/libraries/knex.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const knex = require('knex');
2
2
 
3
- const config = require('@root/config/database');
3
+ const config = require('../config/database');
4
4
 
5
5
  const db = knex(config[process.env.NODE_ENV || 'development']);
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopex/ecopex-framework",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Javascript Framework for API and Admin Panel",
5
5
  "main": "ecosystem.config.js",
6
6
  "scripts": {
@@ -13,7 +13,11 @@
13
13
  "prod": "pm2 start ecosystem.config.js --env production",
14
14
  "migrate": "knex migrate:latest",
15
15
  "migrate:rollback": "knex migrate:rollback",
16
- "seed": "knex seed:run"
16
+ "seed": "knex seed:run",
17
+ "npm:publish": "npm version patch && npm publish"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
17
21
  },
18
22
  "dependencies": {
19
23
  "@aws-sdk/client-s3": "^3.958.0",
package/stores/base.js CHANGED
@@ -1,4 +1,4 @@
1
- const knex = require('@root/libraries/knex');
1
+ const knex = require('../libraries/knex');
2
2
 
3
3
  module.exports = class StoreModel {
4
4
  constructor(name = 'store_model', primary_key = 'id', schema = {}) {
@@ -1,8 +1,8 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
- const handlers = require('@root/routes/auto/handler');
4
- const general = require('@root/libraries/general');
5
- const { add_model } = require('@root/stores');
3
+ const handlers = require('../routes/auto/handler');
4
+ const general = require('../libraries/general');
5
+ const { add_model } = require('../stores');
6
6
 
7
7
  /**
8
8
  * JSON Route Loader
@@ -1,5 +1,5 @@
1
1
  const i18n = require('./i18n');
2
- const db = require('@root/libraries/knex');
2
+ const db = require('../libraries/knex');
3
3
  /**
4
4
  * Middleware utilities for Fastify
5
5
  */
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const JsonRouteLoader = require('./jsonRouteLoader');
4
- const general = require('@root/libraries/general');
4
+ const general = require('../libraries/general');
5
5
 
6
6
  /**
7
7
  * Automatically loads routes from the routes directory
package/.env DELETED
@@ -1,73 +0,0 @@
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
@@ -1,22 +0,0 @@
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
- };
@@ -1,23 +0,0 @@
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
- };
@@ -1,66 +0,0 @@
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
- };
@@ -1,21 +0,0 @@
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
- };
@@ -1,21 +0,0 @@
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
- };
@@ -1,10 +0,0 @@
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');
@@ -1,37 +0,0 @@
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
- };
@@ -1,33 +0,0 @@
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');
@@ -1,37 +0,0 @@
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
- };
@@ -1,62 +0,0 @@
1
- /**
2
- * @param { import("knex").Knex } knex
3
- * @returns { Promise<void> }
4
- */
5
- exports.up = function(knex) {
6
- return knex.schema.createTable('users', function(table) {
7
- // Primary key
8
- table.increments('user_id').primary();
9
-
10
- table.integer('site_id').unsigned().references('site_id').inTable('sites');
11
-
12
- // Basic manager information
13
- table.string('username', 50).notNullable().unique();
14
- table.string('email', 255).nullable().unique();
15
- table.string('password', 255).notNullable();
16
- table.enum('type_user', ['vip', 'new', 'risky']).defaultTo('new');
17
-
18
- // Two-factor authentication fields
19
- table.boolean('two_factor_enabled').defaultTo(false);
20
- table.string('two_factor_secret', 32).nullable(); // TOTP secret
21
- table.string('phone_number', 20).nullable();
22
- table.boolean('phone_verified').defaultTo(false);
23
- table.boolean('email_verified').defaultTo(false);
24
-
25
- // Login security
26
- table.integer('login_attempts').defaultTo(0);
27
- table.timestamp('locked_until').nullable();
28
-
29
- // Password security and reset
30
- table.timestamp('password_changed_at').nullable();
31
- table.string('password_reset_token', 255).nullable();
32
-
33
- // Email verification and reset
34
- table.string('email_verification_token', 255).nullable();
35
-
36
- // Phone verification and reset
37
- table.string('phone_verification_code', 10).nullable();
38
-
39
- // Account security
40
- table.boolean('is_active').defaultTo(true);
41
-
42
- // Audit timestamps
43
- table.timestamps(true, true); // created_at and updated_at
44
-
45
- // Indexes for performance and security
46
- table.index(['type_user']);
47
- table.index(['is_active']);
48
- table.index(['two_factor_enabled']);
49
- table.index(['phone_verified']);
50
- table.index(['email_verified']);
51
- table.index(['created_at']);
52
- table.index(['locked_until']);
53
- });
54
- };
55
-
56
- /**
57
- * @param { import("knex").Knex } knex
58
- * @returns { Promise<void> }
59
- */
60
- exports.down = function(knex) {
61
- return knex.schema.dropTable('users');
62
- };
@@ -1,35 +0,0 @@
1
- /**
2
- * @param { import("knex").Knex } knex
3
- * @returns { Promise<void> }
4
- */
5
- exports.up = function(knex) {
6
- return knex.schema.createTable('language_lines', function(table) {
7
- // Primary key
8
- table.increments('language_line_id').primary();
9
-
10
- // Basic manager information
11
- table.integer('language_id').notNullable();
12
- table.string('group', 50).notNullable();
13
- table.string('key', 50).notNullable();
14
- table.text('text').notNullable();
15
- table.boolean('is_modified').defaultTo(false);
16
-
17
- table.timestamps(true, true);
18
-
19
- table.unique(['language_id', 'group', 'key'], 'language_line_unique_index');
20
- table.index(['language_id'], 'language_line_language_index');
21
- table.index(['group'], 'language_line_group_index');
22
- table.index(['key'], 'language_line_key_index');
23
- table.index(['is_modified'], 'language_line_is_modified_index');
24
- table.index(['created_at'], 'language_line_created_at_index');
25
- table.index(['updated_at'], 'language_line_updated_at_index');
26
- });
27
- };
28
-
29
- /**
30
- * @param { import("knex").Knex } knex
31
- * @returns { Promise<void> }
32
- */
33
- exports.down = function(knex) {
34
- return knex.schema.dropTable('language_lines');
35
- };
@@ -1,18 +0,0 @@
1
- exports.up = knex =>
2
- knex.schema
3
- .createTable('category_groups', table => {
4
- table.increments('category_group_id').primary();
5
- table.integer('site_id').unsigned().references('site_id').inTable('sites');
6
- table.timestamps(true, true);
7
- })
8
- .createTable('category_group_translations', table => {
9
- table.increments('category_group_translation_id').primary();
10
- table.integer('category_group_id').unsigned().references('category_group_id').inTable('category_groups').onDelete('CASCADE');
11
- table.integer('language_id').unsigned().references('language_id').inTable('languages');
12
- table.string('name').notNullable();
13
- });
14
-
15
- exports.down = knex =>
16
- knex.schema
17
- .dropTable('category_group_translations')
18
- .dropTable('category_groups');