feat: add logging, marketplace, and admin enhancements

Database & Migrations:
- Add application_logs table migration for hybrid cloud logging
- Add companies table migration and restructure vendor relationships

Logging System:
- Implement hybrid logging system (database + file)
- Add log_service for centralized log management
- Create admin logs page with filtering and viewing capabilities
- Add init_log_settings.py script for log configuration
- Enhance core logging with database integration

Marketplace Integration:
- Add marketplace admin page with product management
- Create marketplace vendor page with product listings
- Implement marketplace.js for both admin and vendor interfaces
- Add marketplace integration documentation

Admin Enhancements:
- Add imports management page and functionality
- Create settings page for admin configuration
- Add vendor themes management page
- Enhance vendor detail and edit pages
- Improve code quality dashboard and violation details
- Add logs viewing and management
- Update icons guide and shared icon system

Architecture & Documentation:
- Document frontend structure and component architecture
- Document models structure and relationships
- Add vendor-in-token architecture documentation
- Add vendor RBAC (role-based access control) documentation
- Document marketplace integration patterns
- Update architecture patterns documentation

Infrastructure:
- Add platform static files structure (css, img, js)
- Move architecture_scan.py to proper models location
- Update model imports and registrations
- Enhance exception handling
- Update dependency injection patterns

UI/UX:
- Improve vendor edit interface
- Update admin user interface
- Enhance page templates documentation
- Add vendor marketplace interface
This commit is contained in:
2025-12-01 21:51:07 +01:00
parent 915734e9b4
commit cc74970223
56 changed files with 8440 additions and 202 deletions

View File

@@ -0,0 +1,68 @@
"""add application_logs table for hybrid logging
Revision ID: 0bd9ffaaced1
Revises: 7a7ce92593d5
Create Date: 2025-11-29 12:44:55.427245
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '0bd9ffaaced1'
down_revision: Union[str, None] = '7a7ce92593d5'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Create application_logs table
op.create_table(
'application_logs',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=False),
sa.Column('level', sa.String(length=20), nullable=False),
sa.Column('logger_name', sa.String(length=200), nullable=False),
sa.Column('module', sa.String(length=200), nullable=True),
sa.Column('function_name', sa.String(length=100), nullable=True),
sa.Column('line_number', sa.Integer(), nullable=True),
sa.Column('message', sa.Text(), nullable=False),
sa.Column('exception_type', sa.String(length=200), nullable=True),
sa.Column('exception_message', sa.Text(), nullable=True),
sa.Column('stack_trace', sa.Text(), nullable=True),
sa.Column('request_id', sa.String(length=100), nullable=True),
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('vendor_id', sa.Integer(), nullable=True),
sa.Column('context', sa.JSON(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['vendor_id'], ['vendors.id'], ),
sa.PrimaryKeyConstraint('id')
)
# Create indexes for better query performance
op.create_index(op.f('ix_application_logs_id'), 'application_logs', ['id'], unique=False)
op.create_index(op.f('ix_application_logs_timestamp'), 'application_logs', ['timestamp'], unique=False)
op.create_index(op.f('ix_application_logs_level'), 'application_logs', ['level'], unique=False)
op.create_index(op.f('ix_application_logs_logger_name'), 'application_logs', ['logger_name'], unique=False)
op.create_index(op.f('ix_application_logs_request_id'), 'application_logs', ['request_id'], unique=False)
op.create_index(op.f('ix_application_logs_user_id'), 'application_logs', ['user_id'], unique=False)
op.create_index(op.f('ix_application_logs_vendor_id'), 'application_logs', ['vendor_id'], unique=False)
def downgrade() -> None:
# Drop indexes
op.drop_index(op.f('ix_application_logs_vendor_id'), table_name='application_logs')
op.drop_index(op.f('ix_application_logs_user_id'), table_name='application_logs')
op.drop_index(op.f('ix_application_logs_request_id'), table_name='application_logs')
op.drop_index(op.f('ix_application_logs_logger_name'), table_name='application_logs')
op.drop_index(op.f('ix_application_logs_level'), table_name='application_logs')
op.drop_index(op.f('ix_application_logs_timestamp'), table_name='application_logs')
op.drop_index(op.f('ix_application_logs_id'), table_name='application_logs')
# Drop table
op.drop_table('application_logs')

View File

@@ -0,0 +1,77 @@
"""add_companies_table_and_restructure_vendors
Revision ID: d0325d7c0f25
Revises: 0bd9ffaaced1
Create Date: 2025-11-30 14:58:17.165142
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'd0325d7c0f25'
down_revision: Union[str, None] = '0bd9ffaaced1'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Create companies table
op.create_table(
'companies',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('owner_user_id', sa.Integer(), nullable=False),
sa.Column('contact_email', sa.String(), nullable=False),
sa.Column('contact_phone', sa.String(), nullable=True),
sa.Column('website', sa.String(), nullable=True),
sa.Column('business_address', sa.Text(), nullable=True),
sa.Column('tax_number', sa.String(), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False, server_default='true'),
sa.Column('is_verified', sa.Boolean(), nullable=False, server_default='false'),
sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.func.now(), onupdate=sa.func.now()),
sa.ForeignKeyConstraint(['owner_user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_companies_id'), 'companies', ['id'], unique=False)
op.create_index(op.f('ix_companies_name'), 'companies', ['name'], unique=False)
# Use batch mode for SQLite to modify vendors table
with op.batch_alter_table('vendors', schema=None) as batch_op:
# Add company_id column
batch_op.add_column(sa.Column('company_id', sa.Integer(), nullable=True))
batch_op.create_index(batch_op.f('ix_vendors_company_id'), ['company_id'], unique=False)
batch_op.create_foreign_key('fk_vendors_company_id', 'companies', ['company_id'], ['id'])
# Remove old contact fields
batch_op.drop_column('contact_email')
batch_op.drop_column('contact_phone')
batch_op.drop_column('website')
batch_op.drop_column('business_address')
batch_op.drop_column('tax_number')
def downgrade() -> None:
# Use batch mode for SQLite to modify vendors table
with op.batch_alter_table('vendors', schema=None) as batch_op:
# Re-add contact fields to vendors
batch_op.add_column(sa.Column('tax_number', sa.String(), nullable=True))
batch_op.add_column(sa.Column('business_address', sa.Text(), nullable=True))
batch_op.add_column(sa.Column('website', sa.String(), nullable=True))
batch_op.add_column(sa.Column('contact_phone', sa.String(), nullable=True))
batch_op.add_column(sa.Column('contact_email', sa.String(), nullable=True))
# Remove company_id from vendors
batch_op.drop_constraint('fk_vendors_company_id', type_='foreignkey')
batch_op.drop_index(batch_op.f('ix_vendors_company_id'))
batch_op.drop_column('company_id')
# Drop companies table
op.drop_index(op.f('ix_companies_name'), table_name='companies')
op.drop_index(op.f('ix_companies_id'), table_name='companies')
op.drop_table('companies')