Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
352 changes: 114 additions & 238 deletions .env.example

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.head_ref || github.ref }}

- name: Setup Node.js
uses: actions/setup-node@v4
Expand Down Expand Up @@ -187,11 +188,17 @@ jobs:
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"

# Get the current branch name
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
echo "Current branch: $BRANCH_NAME"

git add PROGRESS_REPORT.md

if ! git diff --staged --quiet; then
git commit -m "🤖 Automated progress update - $(date '+%Y-%m-%d %H:%M')"
git push origin main

# Push to the current branch
git push origin HEAD:${{ github.head_ref || github.ref_name }}
else
echo "No changes to commit"
fi
Expand Down
7 changes: 2 additions & 5 deletions ai-service/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ class Settings(BaseSettings):
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")

# Security
API_KEY: str = os.getenv("INTERNAL_API_KEY", "dev-api-key")
API_KEY: str = os.getenv("INTERNAL_API_KEY") or (lambda: (_ for _ in ()).throw(ValueError("INTERNAL_API_KEY environment variable is required for security")))()

# Database
DATABASE_URL: str = os.getenv(
"DATABASE_URL",
"postgresql://modmaster_user:modmaster_password@postgres:5432/modmaster_pro"
)
DATABASE_URL: str = os.getenv("DATABASE_URL") or (lambda: (_ for _ in ()).throw(ValueError("DATABASE_URL environment variable is required")))()

# Redis
REDIS_URL: str = os.getenv("REDIS_URL", "redis://redis:6379/1")
Expand Down
96 changes: 96 additions & 0 deletions backend/api/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
module.exports = {
env: {
node: true,
es2021: true,
jest: true,
},
extends: [
'eslint:recommended',
'airbnb-base',
],
plugins: [
'security',
'node',
],
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
},
rules: {
// Security rules
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'error',
'security/detect-unsafe-regex': 'error',
'security/detect-buffer-noassert': 'error',
'security/detect-child-process': 'error',
'security/detect-disable-mustache-escape': 'error',
'security/detect-eval-with-expression': 'error',
'security/detect-no-csrf-before-method-override': 'error',
'security/detect-non-literal-fs-filename': 'error',
'security/detect-non-literal-require': 'error',
'security/detect-possible-timing-attacks': 'error',
'security/detect-pseudoRandomBytes': 'error',

// Code quality
'no-console': 'warn',
'no-debugger': 'error',
'no-alert': 'error',
'no-eval': 'error',
'no-implied-eval': 'error',
'no-new-func': 'error',
'no-script-url': 'error',
'no-var': 'error',
'prefer-const': 'error',
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-undef': 'error',
'no-global-assign': 'error',

// Node.js specific
'node/no-unsupported-features/es-syntax': 'off',
'node/no-missing-import': 'error',
'node/no-unpublished-import': 'error',
'node/no-extraneous-import': 'error',
'node/no-missing-require': 'error',
'node/no-unpublished-require': 'error',
'node/no-extraneous-require': 'error',

// Import rules
'import/no-unresolved': 'error',
'import/named': 'error',
'import/default': 'error',
'import/namespace': 'error',
'import/no-duplicates': 'error',
'import/order': ['error', {
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
],
'newlines-between': 'always',
}],

// Code style
'indent': ['error', 2],
'linebreak-style': ['error', 'unix'],
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
'comma-dangle': ['error', 'always-multiline'],
'object-curly-spacing': ['error', 'always'],
'array-bracket-spacing': ['error', 'never'],
'max-len': ['error', { code: 100 }],
},
overrides: [
{
files: ['**/*.test.js', '**/*.spec.js'],
env: {
jest: true,
},
rules: {
'no-console': 'off',
},
},
],
};
63 changes: 38 additions & 25 deletions backend/api/knexfile.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
const config = require('./src/config');
require('dotenv').config();

module.exports = {
development: {
client: 'pg',
connection: config.database,
client: 'postgresql',
connection: {
host: process.env.POSTGRES_HOST || 'localhost',
port: process.env.POSTGRES_PORT || 5432,
database: process.env.POSTGRES_DB || 'modmaster_pro',
user: process.env.POSTGRES_USER || 'modmaster_user',
password: process.env.POSTGRES_PASSWORD || (() => {
throw new Error('POSTGRES_PASSWORD environment variable is required for security');
})(),
ssl: process.env.POSTGRES_SSL_MODE === 'require' ? { rejectUnauthorized: false } : false,
},
pool: {
min: parseInt(process.env.DB_POOL_MIN, 10) || 2,
max: parseInt(process.env.DB_POOL_MAX, 10) || 10,
},
migrations: {
directory: './src/database/migrations',
tableName: 'knex_migrations',
Expand All @@ -13,9 +26,22 @@ module.exports = {
},
},

staging: {
client: 'pg',
connection: config.database,
test: {
client: 'postgresql',
connection: {
host: process.env.TEST_POSTGRES_HOST || 'localhost',
port: process.env.TEST_POSTGRES_PORT || 5432,
database: process.env.TEST_POSTGRES_DB || 'modmaster_pro_test',
user: process.env.TEST_POSTGRES_USER || 'modmaster_user',
password: process.env.TEST_POSTGRES_PASSWORD || (() => {
throw new Error('TEST_POSTGRES_PASSWORD environment variable is required for security');
})(),
ssl: false,
},
pool: {
min: 1,
max: 5,
},
migrations: {
directory: './src/database/migrations',
tableName: 'knex_migrations',
Expand All @@ -26,26 +52,13 @@ module.exports = {
},

production: {
client: 'pg',
connection: config.database,
migrations: {
directory: './src/database/migrations',
tableName: 'knex_migrations',
},
client: 'postgresql',
connection: process.env.DATABASE_URL || (() => {
throw new Error('DATABASE_URL environment variable is required for production');
})(),
pool: {
min: 5,
max: 20,
},
},

test: {
client: 'pg',
connection: process.env.TEST_DATABASE_URL || {
host: 'localhost',
port: 5432,
database: 'modmaster_pro_test',
user: 'modmaster_user',
password: 'modmaster_password',
min: parseInt(process.env.DB_POOL_MIN, 10) || 2,
max: parseInt(process.env.DB_POOL_MAX, 10) || 10,
},
migrations: {
directory: './src/database/migrations',
Expand Down
28 changes: 20 additions & 8 deletions backend/api/src/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ const config = {

// Database
database: {
url: process.env.DATABASE_URL || 'postgresql://modmaster_user:modmaster_password@localhost:5432/modmaster_pro',
url: process.env.DATABASE_URL || (() => {
throw new Error('DATABASE_URL environment variable is required');
})(),
host: process.env.POSTGRES_HOST || 'localhost',
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
name: process.env.POSTGRES_DB || 'modmaster_pro',
username: process.env.POSTGRES_USER || 'modmaster_user',
password: process.env.POSTGRES_PASSWORD || 'modmaster_password',
password: process.env.POSTGRES_PASSWORD || (() => {
throw new Error('POSTGRES_PASSWORD environment variable is required for security');
})(),
sslMode: process.env.POSTGRES_SSL_MODE || 'disable',
pool: {
min: parseInt(process.env.DB_POOL_MIN, 10) || 2,
Expand Down Expand Up @@ -50,7 +54,9 @@ const config = {

// JWT Authentication
jwt: {
secret: process.env.JWT_SECRET || 'your_super_secret_jwt_key_change_in_production',
secret: process.env.JWT_SECRET || (() => {
throw new Error('JWT_SECRET environment variable is required for security');
})(),
algorithm: process.env.JWT_ALGORITHM || 'HS256',
expiresIn: process.env.JWT_EXPIRES_IN || '24h',
refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d',
Expand Down Expand Up @@ -115,7 +121,10 @@ const config = {
n8n: {
url: process.env.N8N_URL || 'http://localhost:5678',
username: process.env.N8N_USERNAME || 'admin',
password: process.env.N8N_PASSWORD || 'modmaster123',
password: process.env.N8N_PASSWORD || (() => {
throw new Error('N8N_PASSWORD environment variable is required for security');
})(),
webhookToken: process.env.N8N_WEBHOOK_TOKEN || '',
},
},

Expand Down Expand Up @@ -160,11 +169,14 @@ const config = {
storage: {
provider: process.env.STORAGE_PROVIDER || 'minio',
minio: {
endpoint: process.env.MINIO_ENDPOINT || 'localhost:9000',
accessKey: process.env.MINIO_ACCESS_KEY || 'modmaster_user',
secretKey: process.env.MINIO_SECRET_KEY || 'modmaster_password',
bucket: process.env.MINIO_BUCKET || 'modmaster-pro',
endpoint: process.env.MINIO_ENDPOINT || 'localhost',
port: parseInt(process.env.MINIO_PORT, 10) || 9000,
useSSL: process.env.MINIO_USE_SSL === 'true',
accessKey: process.env.MINIO_ACCESS_KEY || 'modmaster_access_key',
secretKey: process.env.MINIO_SECRET_KEY || (() => {
throw new Error('MINIO_SECRET_KEY environment variable is required for security');
})(),
bucketName: process.env.MINIO_BUCKET_NAME || 'modmaster-pro',
},
aws: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
Expand Down
Loading