refactor(docs/locales): rename project from 'Tуган Як'/'Tugan Yak' to 'Turash' across docs, locales and test fixtures

- Update locales (ru, tt, en) to use 'Turash' and 'Turash AI'
- Update metadata, index.html, and pixel-art README
- Replace example credentials/emails from @tuganyak.dev -> @turash.dev
- Update admin defaults and migration seed to use new admin@turash.dev
- Update docs mentioning the old name
This commit is contained in:
Damir Mukimov 2025-12-15 05:42:16 +01:00
parent 624c907a6e
commit 02fad6713c
16 changed files with 799 additions and 87 deletions

View File

@ -1,6 +1,7 @@
# Admin Panel Concept & Design Specification # Admin Panel Concept & Design Specification
## Table of Contents ## Table of Contents
1. [Overview](#overview) 1. [Overview](#overview)
2. [Architecture & Navigation](#architecture--navigation) 2. [Architecture & Navigation](#architecture--navigation)
3. [Pages & Functionality](#pages--functionality) 3. [Pages & Functionality](#pages--functionality)
@ -13,13 +14,16 @@
## Overview ## Overview
### Purpose ### Purpose
The Admin Panel is a comprehensive management interface for administrators to manage all aspects of the "Tugan Yak" ecosystem, including organizations, content, localizations, users, and system configuration.
The Admin Panel is a comprehensive management interface for administrators to manage all aspects of the "Turash" ecosystem, including organizations, content, localizations, users, and system configuration.
### Target Users ### Target Users
- **Primary**: System Administrators - **Primary**: System Administrators
- **Secondary**: Content Managers (with limited permissions) - **Secondary**: Content Managers (with limited permissions)
### Key Features ### Key Features
- **Unified Dashboard**: Real-time overview of system health and metrics - **Unified Dashboard**: Real-time overview of system health and metrics
- **Organization Management**: Full CRUD operations with verification workflow - **Organization Management**: Full CRUD operations with verification workflow
- **Localization Management**: Complete UI and data translation management - **Localization Management**: Complete UI and data translation management
@ -102,6 +106,7 @@ Admin Panel
``` ```
### Responsive Breakpoints ### Responsive Breakpoints
- **Desktop**: Full sidebar navigation, multi-column layouts - **Desktop**: Full sidebar navigation, multi-column layouts
- **Tablet**: Collapsible sidebar, adapted grid layouts - **Tablet**: Collapsible sidebar, adapted grid layouts
- **Mobile**: Bottom navigation bar, single column, stacked cards - **Mobile**: Bottom navigation bar, single column, stacked cards
@ -115,6 +120,7 @@ Admin Panel
**Purpose**: Central hub providing overview of system status and key metrics. **Purpose**: Central hub providing overview of system status and key metrics.
#### Layout #### Layout
- **Top Row**: Key Metrics Cards (4 cards) - **Top Row**: Key Metrics Cards (4 cards)
- **Middle Row**: Charts (2 columns) - **Middle Row**: Charts (2 columns)
- **Bottom Row**: Recent Activity & Quick Actions - **Bottom Row**: Recent Activity & Quick Actions
@ -122,6 +128,7 @@ Admin Panel
#### Components #### Components
**Key Metrics Cards**: **Key Metrics Cards**:
1. **Total Organizations** 1. **Total Organizations**
- Count with trend indicator (↑/↓ %) - Count with trend indicator (↑/↓ %)
- Click to navigate to Organizations list - Click to navigate to Organizations list
@ -143,6 +150,7 @@ Admin Panel
- Color: Warning - Color: Warning
**Charts Section**: **Charts Section**:
1. **Economic Connections Graph** (Left, 60% width) 1. **Economic Connections Graph** (Left, 60% width)
- Interactive network visualization - Interactive network visualization
- Sector-to-sector connections - Sector-to-sector connections
@ -156,6 +164,7 @@ Admin Panel
- Time period selector - Time period selector
**Recent Activity Feed**: **Recent Activity Feed**:
- Last 20 system events - Last 20 system events
- Organization verifications - Organization verifications
- New user registrations - New user registrations
@ -164,12 +173,14 @@ Admin Panel
- Real-time updates via WebSocket - Real-time updates via WebSocket
**Quick Actions**: **Quick Actions**:
- Verify pending organizations (with count badge) - Verify pending organizations (with count badge)
- Review translation requests - Review translation requests
- View system alerts - View system alerts
- Access help documentation - Access help documentation
#### UX Features #### UX Features
- **Real-time Updates**: WebSocket connection for live metrics - **Real-time Updates**: WebSocket connection for live metrics
- **Refresh Indicator**: Manual refresh button with last update time - **Refresh Indicator**: Manual refresh button with last update time
- **Export Options**: Download dashboard as PDF/PNG - **Export Options**: Download dashboard as PDF/PNG
@ -187,6 +198,7 @@ Admin Panel
##### 2.1 Organization List (`/admin/organizations`) ##### 2.1 Organization List (`/admin/organizations`)
**Features**: **Features**:
- **Advanced Search**: - **Advanced Search**:
- Full-text search (name, description, sector) - Full-text search (name, description, sector)
- Filter by: Sector, Type, Verification Status, Date Range - Filter by: Sector, Type, Verification Status, Date Range
@ -214,6 +226,7 @@ Admin Panel
- Duplicate - Duplicate
**UX Features**: **UX Features**:
- **Inline Editing**: Quick edit for name, sector (with autocomplete) - **Inline Editing**: Quick edit for name, sector (with autocomplete)
- **Keyboard Shortcuts**: - **Keyboard Shortcuts**:
- `Ctrl+F`: Focus search - `Ctrl+F`: Focus search
@ -227,6 +240,7 @@ Admin Panel
**Layout**: Multi-step wizard or single-page form (configurable) **Layout**: Multi-step wizard or single-page form (configurable)
**Sections**: **Sections**:
1. **Basic Information** 1. **Basic Information**
- Name (required, with translation fields) - Name (required, with translation fields)
- Sector (dropdown with search) - Sector (dropdown with search)
@ -263,6 +277,7 @@ Admin Panel
- Custom fields - Custom fields
**UX Features**: **UX Features**:
- **Auto-save**: Draft saved every 30 seconds - **Auto-save**: Draft saved every 30 seconds
- **Validation**: Real-time field validation - **Validation**: Real-time field validation
- **Translation Tabs**: Switch between locales (ru, en, tt) - **Translation Tabs**: Switch between locales (ru, en, tt)
@ -275,6 +290,7 @@ Admin Panel
**Purpose**: Dedicated interface for reviewing and verifying organizations. **Purpose**: Dedicated interface for reviewing and verifying organizations.
**Features**: **Features**:
- **Queue List**: Organizations pending verification - **Queue List**: Organizations pending verification
- **Priority Sorting**: By date, user requests, flags - **Priority Sorting**: By date, user requests, flags
- **Quick Actions**: Approve, Reject, Request More Info - **Quick Actions**: Approve, Reject, Request More Info
@ -288,6 +304,7 @@ Admin Panel
- **Statistics**: Verification rate, average time - **Statistics**: Verification rate, average time
**UX Features**: **UX Features**:
- **Side-by-side View**: Compare with similar verified organizations - **Side-by-side View**: Compare with similar verified organizations
- **Keyboard Navigation**: Arrow keys to navigate queue - **Keyboard Navigation**: Arrow keys to navigate queue
- **Bulk Approve**: Select and approve multiple - **Bulk Approve**: Select and approve multiple
@ -306,12 +323,14 @@ Admin Panel
**Purpose**: Manage all frontend UI text translations. **Purpose**: Manage all frontend UI text translations.
**Layout**: **Layout**:
- **Left Panel**: Translation keys tree (grouped by namespace) - **Left Panel**: Translation keys tree (grouped by namespace)
- **Right Panel**: Translation editor for selected key - **Right Panel**: Translation editor for selected key
**Features**: **Features**:
**Translation Key Tree**: **Translation Key Tree**:
- Hierarchical structure matching frontend structure - Hierarchical structure matching frontend structure
- `common.*` - `common.*`
- `adminPage.*` - `adminPage.*`
@ -324,6 +343,7 @@ Admin Panel
- Show untranslated keys (red indicator) - Show untranslated keys (red indicator)
**Translation Editor**: **Translation Editor**:
- **Key Path**: Full path display (e.g., `adminPage.title`) - **Key Path**: Full path display (e.g., `adminPage.title`)
- **Source Locale** (Russian): Read-only, serves as reference - **Source Locale** (Russian): Read-only, serves as reference
- **Target Locales**: Editable fields for each locale (en, tt) - **Target Locales**: Editable fields for each locale (en, tt)
@ -343,6 +363,7 @@ Admin Panel
- Word count - Word count
**Bulk Operations**: **Bulk Operations**:
- **Bulk Edit**: Edit multiple keys at once - **Bulk Edit**: Edit multiple keys at once
- **Auto-translate**: Translate missing keys using AI/ML - **Auto-translate**: Translate missing keys using AI/ML
- **Import/Export**: - **Import/Export**:
@ -353,6 +374,7 @@ Admin Panel
- **Copy from Locale**: Copy translations from another locale - **Copy from Locale**: Copy translations from another locale
**Translation Tools**: **Translation Tools**:
- **Translation Memory**: Suggest similar translations - **Translation Memory**: Suggest similar translations
- **Spell Check**: Per locale - **Spell Check**: Per locale
- **Placeholder Validation**: Ensure placeholders match (e.g., `{{name}}`) - **Placeholder Validation**: Ensure placeholders match (e.g., `{{name}}`)
@ -360,6 +382,7 @@ Admin Panel
- **Context Preview**: Show where translation is used in UI - **Context Preview**: Show where translation is used in UI
**UX Features**: **UX Features**:
- **Live Preview**: See translation in context - **Live Preview**: See translation in context
- **Keyboard Shortcuts**: - **Keyboard Shortcuts**:
- `Ctrl+S`: Save - `Ctrl+S`: Save
@ -377,6 +400,7 @@ Admin Panel
**Purpose**: Manage translations for dynamic content (organizations, sites, heritage buildings, etc.). **Purpose**: Manage translations for dynamic content (organizations, sites, heritage buildings, etc.).
**Layout**: **Layout**:
- **Entity Type Selector**: Organizations, Sites, Heritage, etc. - **Entity Type Selector**: Organizations, Sites, Heritage, etc.
- **Entity List**: Searchable, filterable list - **Entity List**: Searchable, filterable list
- **Translation Editor**: Similar to UI translations but entity-specific - **Translation Editor**: Similar to UI translations but entity-specific
@ -384,11 +408,13 @@ Admin Panel
**Features**: **Features**:
**Entity Selection**: **Entity Selection**:
- Dropdown or tabs for entity types - Dropdown or tabs for entity types
- Search entities by name/ID - Search entities by name/ID
- Filter by translation status - Filter by translation status
**Entity Translation View**: **Entity Translation View**:
- **Entity Info**: Name, ID, source locale values - **Entity Info**: Name, ID, source locale values
- **Translatable Fields**: - **Translatable Fields**:
- Name - Name
@ -400,6 +426,7 @@ Admin Panel
- **Copy Entity**: Copy translations from similar entity - **Copy Entity**: Copy translations from similar entity
**Translation Workflow**: **Translation Workflow**:
1. Select entity type 1. Select entity type
2. Search/filter entities 2. Search/filter entities
3. Select entity 3. Select entity
@ -408,6 +435,7 @@ Admin Panel
6. Save with review status 6. Save with review status
**Advanced Features**: **Advanced Features**:
- **Translation Suggestions**: AI-powered suggestions based on similar entities - **Translation Suggestions**: AI-powered suggestions based on similar entities
- **Bulk Operations**: - **Bulk Operations**:
- Translate all missing for entity type - Translate all missing for entity type
@ -419,6 +447,7 @@ Admin Panel
- Missing translations count - Missing translations count
**UX Features**: **UX Features**:
- **Side-by-side Comparison**: Source vs. translations - **Side-by-side Comparison**: Source vs. translations
- **Entity Preview**: See how entity appears in different locales - **Entity Preview**: See how entity appears in different locales
- **Translation Queue**: List of entities needing translation - **Translation Queue**: List of entities needing translation
@ -438,6 +467,7 @@ Admin Panel
##### 4.1 Static Pages (`/admin/content/pages`) ##### 4.1 Static Pages (`/admin/content/pages`)
**Features**: **Features**:
- **Page List**: - **Page List**:
- About, Contact, Privacy, Terms, etc. - About, Contact, Privacy, Terms, etc.
- Custom pages - Custom pages
@ -467,6 +497,7 @@ Admin Panel
##### 4.2 Announcements (`/admin/content/announcements`) ##### 4.2 Announcements (`/admin/content/announcements`)
**Features**: **Features**:
- **Announcement List**: - **Announcement List**:
- Title, Status, Date, Priority - Title, Status, Date, Priority
- Filter by status, date range - Filter by status, date range
@ -483,6 +514,7 @@ Admin Panel
##### 4.3 Media Library (`/admin/content/media`) ##### 4.3 Media Library (`/admin/content/media`)
**Features**: **Features**:
- **Media Grid View**: - **Media Grid View**:
- Thumbnails with overlay info - Thumbnails with overlay info
- Filter by type (Image, Video, Document) - Filter by type (Image, Video, Document)
@ -518,6 +550,7 @@ Admin Panel
##### 5.1 User List (`/admin/users`) ##### 5.1 User List (`/admin/users`)
**Features**: **Features**:
- **User Table**: - **User Table**:
- Columns: Avatar, Name, Email, Role, Status, Last Login, Actions - Columns: Avatar, Name, Email, Role, Status, Last Login, Actions
- Sortable, filterable - Sortable, filterable
@ -535,6 +568,7 @@ Admin Panel
##### 5.2 User Editor (`/admin/users/new`, `/admin/users/:id/edit`) ##### 5.2 User Editor (`/admin/users/new`, `/admin/users/:id/edit`)
**Features**: **Features**:
- **Basic Information**: - **Basic Information**:
- Name - Name
- Email (unique validation) - Email (unique validation)
@ -558,6 +592,7 @@ Admin Panel
##### 5.3 Activity Log (`/admin/users/activity`) ##### 5.3 Activity Log (`/admin/users/activity`)
**Features**: **Features**:
- **Activity Feed**: - **Activity Feed**:
- User actions (login, create org, edit, etc.) - User actions (login, create org, edit, etc.)
- Timestamp - Timestamp
@ -581,6 +616,7 @@ Admin Panel
##### 6.1 Overview (`/admin/analytics`) ##### 6.1 Overview (`/admin/analytics`)
**Features**: **Features**:
- **Key Metrics Dashboard**: - **Key Metrics Dashboard**:
- Total users - Total users
- Active users (last 30 days) - Active users (last 30 days)
@ -597,6 +633,7 @@ Admin Panel
##### 6.2 Organization Analytics (`/admin/analytics/organizations`) ##### 6.2 Organization Analytics (`/admin/analytics/organizations`)
**Features**: **Features**:
- **Sector Distribution**: Pie/bar chart - **Sector Distribution**: Pie/bar chart
- **Verification Rate**: Over time - **Verification Rate**: Over time
- **Top Sectors**: By count, by connections - **Top Sectors**: By count, by connections
@ -606,6 +643,7 @@ Admin Panel
##### 6.3 User Activity (`/admin/analytics/users`) ##### 6.3 User Activity (`/admin/analytics/users`)
**Features**: **Features**:
- **User Engagement**: - **User Engagement**:
- Daily/Monthly active users - Daily/Monthly active users
- Session duration - Session duration
@ -617,6 +655,7 @@ Admin Panel
##### 6.4 Matching Statistics (`/admin/analytics/matching`) ##### 6.4 Matching Statistics (`/admin/analytics/matching`)
**Features**: **Features**:
- **Match Success Rate**: Over time - **Match Success Rate**: Over time
- **Top Matched Sectors**: Which sectors match most - **Top Matched Sectors**: Which sectors match most
- **Proposal Statistics**: Sent, accepted, rejected - **Proposal Statistics**: Sent, accepted, rejected
@ -625,6 +664,7 @@ Admin Panel
##### 6.5 Reports (`/admin/analytics/reports`) ##### 6.5 Reports (`/admin/analytics/reports`)
**Features**: **Features**:
- **Report Templates**: - **Report Templates**:
- Monthly summary - Monthly summary
- User activity report - User activity report
@ -645,6 +685,7 @@ Admin Panel
##### 7.1 General Settings (`/admin/settings/general`) ##### 7.1 General Settings (`/admin/settings/general`)
**Features**: **Features**:
- **Site Information**: - **Site Information**:
- Site name - Site name
- Site description - Site description
@ -662,6 +703,7 @@ Admin Panel
##### 7.2 Localization Settings (`/admin/settings/localization`) ##### 7.2 Localization Settings (`/admin/settings/localization`)
**Features**: **Features**:
- **Supported Locales**: - **Supported Locales**:
- Enable/disable locales - Enable/disable locales
- Default locale - Default locale
@ -679,6 +721,7 @@ Admin Panel
##### 7.3 Integrations (`/admin/settings/integrations`) ##### 7.3 Integrations (`/admin/settings/integrations`)
**Features**: **Features**:
- **API Keys**: - **API Keys**:
- External services - External services
- API key management - API key management
@ -695,6 +738,7 @@ Admin Panel
##### 7.4 Email Templates (`/admin/settings/email`) ##### 7.4 Email Templates (`/admin/settings/email`)
**Features**: **Features**:
- **Template List**: - **Template List**:
- Welcome email - Welcome email
- Verification email - Verification email
@ -711,6 +755,7 @@ Admin Panel
##### 7.5 System Maintenance (`/admin/settings/maintenance`) ##### 7.5 System Maintenance (`/admin/settings/maintenance`)
**Features**: **Features**:
- **Maintenance Mode**: - **Maintenance Mode**:
- Enable/disable - Enable/disable
- Custom message - Custom message
@ -738,12 +783,14 @@ Admin Panel
## UX Design Principles ## UX Design Principles
### 1. Consistency ### 1. Consistency
- **Design System**: Use consistent components, colors, typography - **Design System**: Use consistent components, colors, typography
- **Navigation**: Predictable navigation patterns - **Navigation**: Predictable navigation patterns
- **Terminology**: Consistent language throughout - **Terminology**: Consistent language throughout
- **Icons**: Standardized icon set with clear meanings - **Icons**: Standardized icon set with clear meanings
### 2. Efficiency ### 2. Efficiency
- **Keyboard Shortcuts**: Power users can work faster - **Keyboard Shortcuts**: Power users can work faster
- **Bulk Operations**: Perform actions on multiple items - **Bulk Operations**: Perform actions on multiple items
- **Quick Actions**: Common actions easily accessible - **Quick Actions**: Common actions easily accessible
@ -751,6 +798,7 @@ Admin Panel
- **Undo/Redo**: Allow mistake correction - **Undo/Redo**: Allow mistake correction
### 3. Feedback ### 3. Feedback
- **Loading States**: Clear indicators for async operations - **Loading States**: Clear indicators for async operations
- **Success Messages**: Confirm successful actions - **Success Messages**: Confirm successful actions
- **Error Messages**: Clear, actionable error messages - **Error Messages**: Clear, actionable error messages
@ -758,6 +806,7 @@ Admin Panel
- **Notifications**: Non-intrusive notifications system - **Notifications**: Non-intrusive notifications system
### 4. Accessibility ### 4. Accessibility
- **WCAG 2.1 AA Compliance**: Meet accessibility standards - **WCAG 2.1 AA Compliance**: Meet accessibility standards
- **Keyboard Navigation**: Full functionality via keyboard - **Keyboard Navigation**: Full functionality via keyboard
- **Screen Reader Support**: Proper ARIA labels - **Screen Reader Support**: Proper ARIA labels
@ -765,12 +814,14 @@ Admin Panel
- **Focus Indicators**: Clear focus states - **Focus Indicators**: Clear focus states
### 5. Responsiveness ### 5. Responsiveness
- **Mobile-First**: Works on all screen sizes - **Mobile-First**: Works on all screen sizes
- **Touch-Friendly**: Adequate touch targets (44x44px minimum) - **Touch-Friendly**: Adequate touch targets (44x44px minimum)
- **Adaptive Layouts**: Layouts adapt to screen size - **Adaptive Layouts**: Layouts adapt to screen size
- **Performance**: Fast loading, smooth interactions - **Performance**: Fast loading, smooth interactions
### 6. Discoverability ### 6. Discoverability
- **Breadcrumbs**: Show current location - **Breadcrumbs**: Show current location
- **Search**: Global search for quick access - **Search**: Global search for quick access
- **Tooltips**: Helpful hints on hover - **Tooltips**: Helpful hints on hover
@ -778,6 +829,7 @@ Admin Panel
- **Onboarding**: Guided tour for new admins - **Onboarding**: Guided tour for new admins
### 7. Error Prevention ### 7. Error Prevention
- **Validation**: Real-time field validation - **Validation**: Real-time field validation
- **Confirmations**: For destructive actions - **Confirmations**: For destructive actions
- **Draft Saving**: Auto-save to prevent data loss - **Draft Saving**: Auto-save to prevent data loss
@ -785,6 +837,7 @@ Admin Panel
- **Clear Labels**: Unambiguous field labels - **Clear Labels**: Unambiguous field labels
### 8. Performance ### 8. Performance
- **Lazy Loading**: Load content as needed - **Lazy Loading**: Load content as needed
- **Pagination**: Efficient data loading - **Pagination**: Efficient data loading
- **Optimistic Updates**: Immediate UI feedback - **Optimistic Updates**: Immediate UI feedback
@ -798,6 +851,7 @@ Admin Panel
### Frontend Architecture ### Frontend Architecture
**Technology Stack**: **Technology Stack**:
- **Framework**: React 18+ with TypeScript - **Framework**: React 18+ with TypeScript
- **Routing**: React Router v6 - **Routing**: React Router v6
- **State Management**: React Query for server state, Zustand for client state - **State Management**: React Query for server state, Zustand for client state
@ -809,6 +863,7 @@ Admin Panel
- **Rich Text**: Tiptap or similar - **Rich Text**: Tiptap or similar
**Component Structure**: **Component Structure**:
``` ```
components/ components/
admin/ admin/
@ -849,6 +904,7 @@ components/
``` ```
**Routing Structure**: **Routing Structure**:
```typescript ```typescript
/admin /admin
/dashboard /dashboard
@ -883,6 +939,7 @@ components/
### Backend Architecture ### Backend Architecture
**API Endpoints Structure**: **API Endpoints Structure**:
``` ```
/api/v1/admin/ /api/v1/admin/
/organizations /organizations
@ -951,6 +1008,7 @@ components/
``` ```
**Middleware**: **Middleware**:
- Authentication required for all admin routes - Authentication required for all admin routes
- Role check: Must be `admin` role - Role check: Must be `admin` role
- Rate limiting for admin endpoints - Rate limiting for admin endpoints
@ -961,23 +1019,27 @@ components/
## API Requirements ## API Requirements
### Authentication & Authorization ### Authentication & Authorization
- All admin endpoints require JWT authentication - All admin endpoints require JWT authentication
- Role-based access: Only users with `admin` role - Role-based access: Only users with `admin` role
- Audit logging for all admin actions - Audit logging for all admin actions
### Response Formats ### Response Formats
- Consistent JSON response structure - Consistent JSON response structure
- Error responses with proper HTTP status codes - Error responses with proper HTTP status codes
- Pagination for list endpoints - Pagination for list endpoints
- Filtering and sorting support - Filtering and sorting support
### Performance ### Performance
- Pagination: Default 25 items, max 100 - Pagination: Default 25 items, max 100
- Caching: Cache frequently accessed data - Caching: Cache frequently accessed data
- Rate limiting: Prevent abuse - Rate limiting: Prevent abuse
- Bulk operations: Support batch processing - Bulk operations: Support batch processing
### Data Validation ### Data Validation
- Input validation on all endpoints - Input validation on all endpoints
- Type checking - Type checking
- Business rule validation - Business rule validation
@ -988,30 +1050,35 @@ components/
## Implementation Phases ## Implementation Phases
### Phase 1: Foundation (Week 1-2) ### Phase 1: Foundation (Week 1-2)
- Admin layout and navigation - Admin layout and navigation
- Dashboard with basic metrics - Dashboard with basic metrics
- Organization management (enhance existing) - Organization management (enhance existing)
- User management basics - User management basics
### Phase 2: Localization (Week 3-4) ### Phase 2: Localization (Week 3-4)
- UI translation management - UI translation management
- Data translation management - Data translation management
- Translation tools and bulk operations - Translation tools and bulk operations
- Import/export functionality - Import/export functionality
### Phase 3: Content Management (Week 5-6) ### Phase 3: Content Management (Week 5-6)
- Static page management - Static page management
- Announcement system - Announcement system
- Media library - Media library
- Rich text editing - Rich text editing
### Phase 4: Analytics (Week 7-8) ### Phase 4: Analytics (Week 7-8)
- Analytics dashboard - Analytics dashboard
- Charts and visualizations - Charts and visualizations
- Reporting system - Reporting system
- Export functionality - Export functionality
### Phase 5: Settings & Polish (Week 9-10) ### Phase 5: Settings & Polish (Week 9-10)
- System settings - System settings
- Integration management - Integration management
- Email templates - Email templates
@ -1024,17 +1091,20 @@ components/
## Success Metrics ## Success Metrics
### Usability ### Usability
- Task completion rate > 90% - Task completion rate > 90%
- Average time to complete common tasks - Average time to complete common tasks
- User satisfaction score - User satisfaction score
- Error rate < 5% - Error rate < 5%
### Performance ### Performance
- Page load time < 2 seconds - Page load time < 2 seconds
- API response time < 500ms (p95) - API response time < 500ms (p95)
- Zero critical bugs in production - Zero critical bugs in production
### Adoption ### Adoption
- Admin user engagement - Admin user engagement
- Feature usage statistics - Feature usage statistics
- Support ticket reduction - Support ticket reduction
@ -1059,7 +1129,6 @@ components/
## Conclusion ## Conclusion
This admin panel concept provides a comprehensive, user-friendly interface for managing all aspects of the "Tugan Yak" ecosystem. The design prioritizes efficiency, usability, and maintainability while providing powerful features for content and localization management. This admin panel concept provides a comprehensive, user-friendly interface for managing all aspects of the "Turash" ecosystem. The design prioritizes efficiency, usability, and maintainability while providing powerful features for content and localization management.
The phased implementation approach allows for iterative development and early value delivery, while the modular architecture ensures scalability and extensibility for future needs. The phased implementation approach allows for iterative development and early value delivery, while the modular architecture ensures scalability and extensibility for future needs.

View File

@ -1,4 +1,4 @@
# Community Features Proposal: Making Turash/Tugan Yak a Daily-Use Tool # Community Features Proposal: Making Turash a Daily-Use Tool
## Executive Summary ## Executive Summary
@ -9,6 +9,7 @@ This document proposes community-focused features and services that will transfo
## Current State Analysis ## Current State Analysis
### Existing Features ### Existing Features
- ✅ Business/Organization registration and profiles - ✅ Business/Organization registration and profiles
- ✅ Resource matching engine (heat, water, waste, by-products) - ✅ Resource matching engine (heat, water, waste, by-products)
- ✅ Interactive map view with organizations - ✅ Interactive map view with organizations
@ -17,6 +18,7 @@ This document proposes community-focused features and services that will transfo
- ✅ Basic public pages (About, Contact, Privacy) - ✅ Basic public pages (About, Contact, Privacy)
### Gaps for Community Engagement ### Gaps for Community Engagement
- ❌ No citizen/community member features - ❌ No citizen/community member features
- ❌ Limited public engagement beyond business matching - ❌ Limited public engagement beyond business matching
- ❌ No regular-use features for non-business users - ❌ No regular-use features for non-business users
@ -32,6 +34,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Show citizens the environmental and economic impact of industrial symbiosis in their city. **Purpose**: Show citizens the environmental and economic impact of industrial symbiosis in their city.
#### Features: #### Features:
- **Real-time Impact Metrics** - **Real-time Impact Metrics**
- Total CO₂ saved (tonnes) - Total CO₂ saved (tonnes)
- Total waste diverted from landfills (tonnes) - Total waste diverted from landfills (tonnes)
@ -59,6 +62,7 @@ This document proposes community-focused features and services that will transfo
- "This Month's Top Connection" feature - "This Month's Top Connection" feature
**Why This Works**: **Why This Works**:
- Creates transparency and trust - Creates transparency and trust
- Citizens can see tangible environmental benefits - Citizens can see tangible environmental benefits
- Encourages businesses to participate (social proof) - Encourages businesses to participate (social proof)
@ -71,6 +75,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Extend resource sharing beyond businesses to include community members, creating a circular economy marketplace. **Purpose**: Extend resource sharing beyond businesses to include community members, creating a circular economy marketplace.
#### Features: #### Features:
- **Community Resource Exchange** - **Community Resource Exchange**
- Citizens can list: surplus materials, tools, equipment, food - Citizens can list: surplus materials, tools, equipment, food
- Categories: Tools, Furniture, Electronics, Building Materials, Food, Textiles - Categories: Tools, Furniture, Electronics, Building Materials, Food, Textiles
@ -96,6 +101,7 @@ This document proposes community-focused features and services that will transfo
- Integration with local food banks - Integration with local food banks
**Why This Works**: **Why This Works**:
- Daily-use feature for citizens - Daily-use feature for citizens
- Reduces waste, supports circular economy - Reduces waste, supports circular economy
- Builds community connections - Builds community connections
@ -108,6 +114,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Become the go-to source for local sustainability and business news. **Purpose**: Become the go-to source for local sustainability and business news.
#### Features: #### Features:
- **Sustainability News Feed** - **Sustainability News Feed**
- Local environmental news - Local environmental news
- Business sustainability initiatives - Business sustainability initiatives
@ -135,6 +142,7 @@ This document proposes community-focused features and services that will transfo
- Downloadable PDF reports - Downloadable PDF reports
**Why This Works**: **Why This Works**:
- Regular content updates drive daily visits - Regular content updates drive daily visits
- Positions platform as community information hub - Positions platform as community information hub
- Increases SEO and discoverability - Increases SEO and discoverability
@ -147,6 +155,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Engage citizens in data collection and environmental monitoring. **Purpose**: Engage citizens in data collection and environmental monitoring.
#### Features: #### Features:
- **Air Quality Reporting** - **Air Quality Reporting**
- Citizens can report air quality observations - Citizens can report air quality observations
- Integration with official air quality sensors (if available) - Integration with official air quality sensors (if available)
@ -178,6 +187,7 @@ This document proposes community-focused features and services that will transfo
- Integration with city environmental department - Integration with city environmental department
**Why This Works**: **Why This Works**:
- Engages environmentally conscious citizens - Engages environmentally conscious citizens
- Creates valuable data for city planning - Creates valuable data for city planning
- Regular participation opportunities - Regular participation opportunities
@ -190,6 +200,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Create spaces for community dialogue about sustainability and local issues. **Purpose**: Create spaces for community dialogue about sustainability and local issues.
#### Features: #### Features:
- **Sustainability Discussion Forums** - **Sustainability Discussion Forums**
- Topics: Circular economy, waste reduction, energy efficiency - Topics: Circular economy, waste reduction, energy efficiency
- Business-citizen dialogue - Business-citizen dialogue
@ -215,6 +226,7 @@ This document proposes community-focused features and services that will transfo
- Community-contributed content - Community-contributed content
**Why This Works**: **Why This Works**:
- Builds community around platform - Builds community around platform
- Increases time spent on platform - Increases time spent on platform
- Creates valuable content archive - Creates valuable content archive
@ -227,6 +239,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Educate community about circular economy, sustainability, and industrial symbiosis. **Purpose**: Educate community about circular economy, sustainability, and industrial symbiosis.
#### Features: #### Features:
- **Interactive Learning Modules** - **Interactive Learning Modules**
- "What is Industrial Symbiosis?" (animated explainer) - "What is Industrial Symbiosis?" (animated explainer)
- "How Circular Economy Works" (interactive diagrams) - "How Circular Economy Works" (interactive diagrams)
@ -258,6 +271,7 @@ This document proposes community-focused features and services that will transfo
- Interactive games and quizzes - Interactive games and quizzes
**Why This Works**: **Why This Works**:
- Positions platform as educational resource - Positions platform as educational resource
- Increases time on site - Increases time on site
- Builds long-term engagement - Builds long-term engagement
@ -270,6 +284,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Motivate participation through challenges, competitions, and rewards. **Purpose**: Motivate participation through challenges, competitions, and rewards.
#### Features: #### Features:
- **Monthly Sustainability Challenges** - **Monthly Sustainability Challenges**
- "Zero Waste Week" - "Zero Waste Week"
- "Energy Saving Month" - "Energy Saving Month"
@ -301,6 +316,7 @@ This document proposes community-focused features and services that will transfo
- Community groups - Community groups
**Why This Works**: **Why This Works**:
- Increases engagement and retention - Increases engagement and retention
- Creates social motivation - Creates social motivation
- Encourages regular participation - Encourages regular participation
@ -313,6 +329,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Support local economy while promoting sustainability. **Purpose**: Support local economy while promoting sustainability.
#### Features: #### Features:
- **Sustainable Business Directory** - **Sustainable Business Directory**
- All businesses on platform (with sustainability badges) - All businesses on platform (with sustainability badges)
- Filter by: sustainability practices, certifications, resource types - Filter by: sustainability practices, certifications, resource types
@ -338,6 +355,7 @@ This document proposes community-focused features and services that will transfo
- Feedback and suggestions - Feedback and suggestions
**Why This Works**: **Why This Works**:
- Supports local economy - Supports local economy
- Creates value for businesses beyond matching - Creates value for businesses beyond matching
- Increases business participation - Increases business participation
@ -350,6 +368,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Facilitate community organizing and volunteer coordination. **Purpose**: Facilitate community organizing and volunteer coordination.
#### Features: #### Features:
- **Volunteer Opportunities Board** - **Volunteer Opportunities Board**
- Environmental cleanup events - Environmental cleanup events
- Community garden projects - Community garden projects
@ -375,6 +394,7 @@ This document proposes community-focused features and services that will transfo
- Mentorship programs - Mentorship programs
**Why This Works**: **Why This Works**:
- Builds active community - Builds active community
- Creates offline engagement - Creates offline engagement
- Strengthens platform value - Strengthens platform value
@ -387,6 +407,7 @@ This document proposes community-focused features and services that will transfo
**Purpose**: Enable on-the-go access and location-based features. **Purpose**: Enable on-the-go access and location-based features.
#### Features: #### Features:
- **Push Notifications** - **Push Notifications**
- New matches for your business - New matches for your business
- Community events nearby - Community events nearby
@ -411,6 +432,7 @@ This document proposes community-focused features and services that will transfo
- Sync when online - Sync when online
**Why This Works**: **Why This Works**:
- Increases accessibility - Increases accessibility
- Enables real-time engagement - Enables real-time engagement
- Location-based features add value - Location-based features add value
@ -421,6 +443,7 @@ This document proposes community-focused features and services that will transfo
## Implementation Priority ## Implementation Priority
### Phase 1: Foundation (Weeks 1-4) ### Phase 1: Foundation (Weeks 1-4)
**Goal**: Add basic community features to drive initial engagement **Goal**: Add basic community features to drive initial engagement
1. **Community Impact Dashboard** 1. **Community Impact Dashboard**
@ -439,6 +462,7 @@ This document proposes community-focused features and services that will transfo
- Contact mechanism - Contact mechanism
**Expected Outcome**: **Expected Outcome**:
- 50-100 daily active users (citizens) - 50-100 daily active users (citizens)
- 2-3 community resource exchanges per week - 2-3 community resource exchanges per week
- Increased time on site - Increased time on site
@ -446,6 +470,7 @@ This document proposes community-focused features and services that will transfo
--- ---
### Phase 2: Engagement (Weeks 5-8) ### Phase 2: Engagement (Weeks 5-8)
**Goal**: Increase engagement and build community **Goal**: Increase engagement and build community
4. **Community Forums** 4. **Community Forums**
@ -464,6 +489,7 @@ This document proposes community-focused features and services that will transfo
- Resource guides - Resource guides
**Expected Outcome**: **Expected Outcome**:
- 200-300 daily active users - 200-300 daily active users
- Active forum discussions - Active forum discussions
- Regular citizen reports - Regular citizen reports
@ -471,6 +497,7 @@ This document proposes community-focused features and services that will transfo
--- ---
### Phase 3: Advanced Features (Weeks 9-12) ### Phase 3: Advanced Features (Weeks 9-12)
**Goal**: Create comprehensive community platform **Goal**: Create comprehensive community platform
7. **Gamification** 7. **Gamification**
@ -489,6 +516,7 @@ This document proposes community-focused features and services that will transfo
- Community groups - Community groups
**Expected Outcome**: **Expected Outcome**:
- 500+ daily active users - 500+ daily active users
- Active community participation - Active community participation
- Regular challenges and events - Regular challenges and events
@ -496,6 +524,7 @@ This document proposes community-focused features and services that will transfo
--- ---
### Phase 4: Mobile & Advanced (Months 4-6) ### Phase 4: Mobile & Advanced (Months 4-6)
**Goal**: Mobile access and advanced features **Goal**: Mobile access and advanced features
10. **Mobile App** 10. **Mobile App**
@ -514,6 +543,7 @@ This document proposes community-focused features and services that will transfo
- API for external developers - API for external developers
**Expected Outcome**: **Expected Outcome**:
- 1000+ daily active users - 1000+ daily active users
- Mobile-first engagement - Mobile-first engagement
- Platform becomes essential tool - Platform becomes essential tool
@ -639,6 +669,7 @@ CREATE TABLE user_badges (
## Success Metrics ## Success Metrics
### Engagement Metrics ### Engagement Metrics
- **Daily Active Users (DAU)**: Target 1000+ by month 6 - **Daily Active Users (DAU)**: Target 1000+ by month 6
- **Monthly Active Users (MAU)**: Target 5000+ by month 6 - **Monthly Active Users (MAU)**: Target 5000+ by month 6
- **Average Session Duration**: Target 5+ minutes - **Average Session Duration**: Target 5+ minutes
@ -646,6 +677,7 @@ CREATE TABLE user_badges (
- **Return Visitor Rate**: Target 40%+ - **Return Visitor Rate**: Target 40%+
### Community Metrics ### Community Metrics
- **Community Resource Listings**: Target 100+ active listings - **Community Resource Listings**: Target 100+ active listings
- **Environmental Reports**: Target 50+ reports per month - **Environmental Reports**: Target 50+ reports per month
- **Forum Posts**: Target 200+ posts per month - **Forum Posts**: Target 200+ posts per month
@ -653,6 +685,7 @@ CREATE TABLE user_badges (
- **Challenge Participants**: Target 200+ participants per challenge - **Challenge Participants**: Target 200+ participants per challenge
### Business Impact Metrics ### Business Impact Metrics
- **Business Registrations**: Increase by 30% due to community visibility - **Business Registrations**: Increase by 30% due to community visibility
- **Resource Connections**: Increase by 25% due to community engagement - **Resource Connections**: Increase by 25% due to community engagement
- **Business-Citizen Interactions**: Track dialogue and feedback - **Business-Citizen Interactions**: Track dialogue and feedback
@ -662,10 +695,12 @@ CREATE TABLE user_badges (
## Monetization Opportunities ## Monetization Opportunities
### Community Features (Free) ### Community Features (Free)
- Basic community features remain free to drive engagement - Basic community features remain free to drive engagement
- Creates network effects and platform value - Creates network effects and platform value
### Premium Community Features (Optional) ### Premium Community Features (Optional)
- **Premium Citizen Accounts**: €5/month - **Premium Citizen Accounts**: €5/month
- Advanced analytics - Advanced analytics
- Priority support - Priority support
@ -673,6 +708,7 @@ CREATE TABLE user_badges (
- Exclusive content - Exclusive content
### Business Opportunities ### Business Opportunities
- **Sponsored Content**: Businesses can sponsor news articles - **Sponsored Content**: Businesses can sponsor news articles
- **Featured Listings**: Businesses can pay for featured placement - **Featured Listings**: Businesses can pay for featured placement
- **Event Sponsorship**: Businesses can sponsor community events - **Event Sponsorship**: Businesses can sponsor community events
@ -693,27 +729,35 @@ CREATE TABLE user_badges (
## Risks & Mitigations ## Risks & Mitigations
### Risk 1: Low Initial Engagement ### Risk 1: Low Initial Engagement
**Mitigation**: **Mitigation**:
- Start with high-value features (Impact Dashboard, News) - Start with high-value features (Impact Dashboard, News)
- Partner with local organizations for content - Partner with local organizations for content
- Active community management - Active community management
### Risk 2: Content Moderation Burden ### Risk 2: Content Moderation Burden
**Mitigation**: **Mitigation**:
- Automated moderation tools - Automated moderation tools
- Community moderators - Community moderators
- Clear community guidelines - Clear community guidelines
- Reporting mechanisms - Reporting mechanisms
### Risk 3: Feature Bloat ### Risk 3: Feature Bloat
**Mitigation**: **Mitigation**:
- Phased rollout - Phased rollout
- User feedback loops - User feedback loops
- Analytics-driven feature prioritization - Analytics-driven feature prioritization
- Regular feature audits - Regular feature audits
### Risk 4: Resource Requirements ### Risk 4: Resource Requirements
**Mitigation**: **Mitigation**:
- Start with MVP features - Start with MVP features
- Leverage existing infrastructure - Leverage existing infrastructure
- Community-contributed content - Community-contributed content
@ -734,7 +778,7 @@ CREATE TABLE user_badges (
## Conclusion ## Conclusion
By adding community-focused features, Turash/Tugan Yak can transform from a B2B matching platform into a comprehensive community engagement tool. These features will: By adding community-focused features, Turash can transform from a B2B matching platform into a comprehensive community engagement tool. These features will:
- **Drive Regular Usage**: Daily-use features keep users coming back - **Drive Regular Usage**: Daily-use features keep users coming back
- **Build Community**: Forums, events, and challenges create engagement - **Build Community**: Forums, events, and challenges create engagement
@ -750,4 +794,3 @@ The phased approach allows for iterative development, user feedback, and resourc
**Last Updated**: 2025-01-27 **Last Updated**: 2025-01-27
**Author**: AI Assistant **Author**: AI Assistant
**Status**: Proposal - Awaiting Review **Status**: Proposal - Awaiting Review

View File

@ -145,7 +145,7 @@ curl http://localhost:8080/health
# Login (if authentication enabled) # Login (if authentication enabled)
curl -X POST http://localhost:8080/auth/login \ curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"email":"admin@tuganyak.dev","password":"admin"}' -d '{"email":"admin@turash.dev","password":"admin"}'
# List businesses # List businesses
curl http://localhost:8080/api/organizations curl http://localhost:8080/api/organizations

View File

@ -36,6 +36,7 @@ backend/
## Implemented Features ## Implemented Features
### ✅ **Enhanced Match Entity with State Management** ### ✅ **Enhanced Match Entity with State Management**
- **Match Lifecycle**: `suggested``negotiating``reserved``contracted``live` - **Match Lifecycle**: `suggested``negotiating``reserved``contracted``live`
- **Negotiation History**: Complete audit trail with timestamps, actors, and notes - **Negotiation History**: Complete audit trail with timestamps, actors, and notes
- **Contract Details**: Signed contracts with terms, effective dates, and attachments - **Contract Details**: Signed contracts with terms, effective dates, and attachments
@ -43,6 +44,7 @@ backend/
- **Event Publishing**: Automatic event publishing on match creation/updates - **Event Publishing**: Automatic event publishing on match creation/updates
### ✅ **Sophisticated Matching Engine** ### ✅ **Sophisticated Matching Engine**
Multi-stage pipeline with advanced algorithms: Multi-stage pipeline with advanced algorithms:
1. **Pre-filtering**: Geographic (accurate Haversine/Vincenty distances), type, and basic quality filtering 1. **Pre-filtering**: Geographic (accurate Haversine/Vincenty distances), type, and basic quality filtering
@ -54,6 +56,7 @@ Multi-stage pipeline with advanced algorithms:
4. **Weighted Scoring**: Multi-criteria ranking with risk penalties 4. **Weighted Scoring**: Multi-criteria ranking with risk penalties
### ✅ **Advanced Economic Calculator** ⭐ **EXTENDED** ### ✅ **Advanced Economic Calculator** ⭐ **EXTENDED**
Comprehensive financial analysis package with advanced features: Comprehensive financial analysis package with advanced features:
- **NPV/IRR/Payback**: Industry-standard financial metrics with risk-adjusted calculations - **NPV/IRR/Payback**: Industry-standard financial metrics with risk-adjusted calculations
@ -67,6 +70,7 @@ Comprehensive financial analysis package with advanced features:
- **Configuration-Driven**: All parameters configurable via config - **Configuration-Driven**: All parameters configurable via config
### ✅ **Geospatial Package** ⭐ **NEW** ### ✅ **Geospatial Package** ⭐ **NEW**
Comprehensive toolkit for geographic calculations: Comprehensive toolkit for geographic calculations:
- **Distance Calculations**: Haversine (fast, accurate) and Vincenty (high precision) formulas - **Distance Calculations**: Haversine (fast, accurate) and Vincenty (high precision) formulas
@ -82,6 +86,7 @@ Comprehensive toolkit for geographic calculations:
**Impact**: Fixed critical bug where distance calculations were hardcoded to 10km. Matching service now uses accurate geographic calculations. **Impact**: Fixed critical bug where distance calculations were hardcoded to 10km. Matching service now uses accurate geographic calculations.
### ✅ **Event-Driven Architecture** ### ✅ **Event-Driven Architecture**
Real-time event processing with Redis Streams: Real-time event processing with Redis Streams:
- **Event Types**: Resource flow, organization, match lifecycle events - **Event Types**: Resource flow, organization, match lifecycle events
@ -91,6 +96,7 @@ Real-time event processing with Redis Streams:
- **Graceful Degradation**: Continues without Redis/WebSocket if unavailable - **Graceful Degradation**: Continues without Redis/WebSocket if unavailable
### ✅ **Clean Architecture** ### ✅ **Clean Architecture**
- **Single Responsibility**: Each service/component has clear boundaries - **Single Responsibility**: Each service/component has clear boundaries
- **Event Integration**: Services publish events, event handlers react asynchronously - **Event Integration**: Services publish events, event handlers react asynchronously
- **Context Propagation**: User/org ID extraction from request context - **Context Propagation**: User/org ID extraction from request context
@ -99,26 +105,31 @@ Real-time event processing with Redis Streams:
### ✅ **API Endpoints** ### ✅ **API Endpoints**
#### Authentication #### Authentication
- `POST /auth/login` - JWT authentication (`admin@tuganyak.dev` / `admin`)
- `POST /auth/login` - JWT authentication (`admin@turash.dev` / `admin`)
#### Organizations (Public) #### Organizations (Public)
- `GET /api/organizations` - List all organizations - `GET /api/organizations` - List all organizations
- `GET /api/organizations/:id` - Get organization by ID - `GET /api/organizations/:id` - Get organization by ID
- `GET /api/organizations/subtype/:subtype` - Filter by subtype - `GET /api/organizations/subtype/:subtype` - Filter by subtype
- `GET /api/organizations/sector/:sector` - Filter by sector - `GET /api/organizations/sector/:sector` - Filter by sector
#### Sites (Public) #### Sites (Public)
- `GET /api/sites` - List all sites - `GET /api/sites` - List all sites
- `GET /api/sites/:id` - Get site by ID - `GET /api/sites/:id` - Get site by ID
- `GET /api/sites/nearby` - Find sites within radius - `GET /api/sites/nearby` - Find sites within radius
- `GET /api/sites/organization/:organizationId` - Get sites by organization - `GET /api/sites/organization/:organizationId` - Get sites by organization
#### Resource Flows (Public) #### Resource Flows (Public)
- `GET /api/resources/:id` - Get resource flow by ID - `GET /api/resources/:id` - Get resource flow by ID
- `GET /api/resources/site/:siteId` - Get flows by site - `GET /api/resources/site/:siteId` - Get flows by site
- `GET /api/resources/organization/:organizationId` - Get flows by organization - `GET /api/resources/organization/:organizationId` - Get flows by organization
#### Matching Engine ⭐ (Public) #### Matching Engine ⭐ (Public)
- `POST /api/matching/query` - Find matches with criteria - `POST /api/matching/query` - Find matches with criteria
- `POST /api/matching/create-from-query` - Create match from query result - `POST /api/matching/create-from-query` - Create match from query result
- `GET /api/matching/:matchId` - Get match details - `GET /api/matching/:matchId` - Get match details
@ -126,9 +137,11 @@ Real-time event processing with Redis Streams:
- `GET /api/matching/top` - Get top matches - `GET /api/matching/top` - Get top matches
#### Real-Time Updates #### Real-Time Updates
- `GET /api/ws?org={orgId}&user={userId}` - WebSocket connection for real-time notifications - `GET /api/ws?org={orgId}&user={userId}` - WebSocket connection for real-time notifications
#### Protected Endpoints (Require Authentication) #### Protected Endpoints (Require Authentication)
- `POST /api/organizations` - Create organization - `POST /api/organizations` - Create organization
- `PUT /api/organizations/:id` - Update organization - `PUT /api/organizations/:id` - Update organization
- `DELETE /api/organizations/:id` - Delete organization - `DELETE /api/organizations/:id` - Delete organization
@ -313,6 +326,7 @@ ws.onmessage = (event) => {
### ✅ **COMPLETED (85% Complete)** ### ✅ **COMPLETED (85% Complete)**
#### Core Architecture #### Core Architecture
- ✅ **Enhanced Match Entity**: State management, negotiation history, contracts - ✅ **Enhanced Match Entity**: State management, negotiation history, contracts
- ✅ **Sophisticated Matching Engine**: Multi-stage pipeline, advanced scoring - ✅ **Sophisticated Matching Engine**: Multi-stage pipeline, advanced scoring
- ✅ **Advanced Economic Calculator**: NPV/IRR/payback, CO₂ quantification - ✅ **Advanced Economic Calculator**: NPV/IRR/payback, CO₂ quantification
@ -321,13 +335,15 @@ ws.onmessage = (event) => {
- ✅ **Clean Architecture**: Proper separation, event integration, context propagation - ✅ **Clean Architecture**: Proper separation, event integration, context propagation
#### Database & APIs #### Database & APIs
- ✅ **PostgreSQL + PostGIS**: Production database with spatial operations - ✅ **PostgreSQL + PostGIS**: Production database with spatial operations
- ✅ **GORM ORM**: Type-safe database operations with auto-migrations - ✅ **GORM ORM**: Type-safe database operations with auto-migrations
- ✅ **REST API**: Complete CRUD operations for all entities - ✅ **REST API**: Complete CRUD operations for all entities
- ✅ **Real-Time API**: WebSocket endpoint for live match updates - ✅ **Real-Time API**: WebSocket endpoint for live match updates
- ✅ **Authentication**: JWT-based auth (admin@tuganyak.dev / admin) - ✅ **Authentication**: JWT-based auth (<admin@turash.dev> / admin)
#### Advanced Features #### Advanced Features
- ✅ **Multi-Criteria Scoring**: Technical, economic, temporal, quality factors - ✅ **Multi-Criteria Scoring**: Technical, economic, temporal, quality factors
- ✅ **Risk Assessment**: Technical, regulatory, market, counterparty risks - ✅ **Risk Assessment**: Technical, regulatory, market, counterparty risks
- ✅ **Geographic Filtering**: Haversine distance calculations - ✅ **Geographic Filtering**: Haversine distance calculations
@ -339,6 +355,7 @@ ws.onmessage = (event) => {
## 🔄 **IN PROGRESS (10%)** ## 🔄 **IN PROGRESS (10%)**
### Advanced Economic Calculator Extensions ### Advanced Economic Calculator Extensions
- ✅ **Basic NPV/IRR/Payback**: Implemented and tested - ✅ **Basic NPV/IRR/Payback**: Implemented and tested
- 🔄 **Sensitivity Analysis**: Framework exists, needs completion - 🔄 **Sensitivity Analysis**: Framework exists, needs completion
- 🔄 **Risk Assessment Integration**: Basic structure, needs enhancement - 🔄 **Risk Assessment Integration**: Basic structure, needs enhancement
@ -349,18 +366,21 @@ ws.onmessage = (event) => {
## ⏳ **REMAINING WORK (5%)** ## ⏳ **REMAINING WORK (5%)**
### Priority 1: Complete Economic Calculator (2 weeks) ### Priority 1: Complete Economic Calculator (2 weeks)
1. **Sensitivity Analysis**: Generate NPV/IRR variations for key parameters 1. **Sensitivity Analysis**: Generate NPV/IRR variations for key parameters
2. **Risk-Adjusted Metrics**: Calculate confidence-adjusted economic values 2. **Risk-Adjusted Metrics**: Calculate confidence-adjusted economic values
3. **CO₂ Impact Breakdown**: Detailed breakdown by transport, process, waste 3. **CO₂ Impact Breakdown**: Detailed breakdown by transport, process, waste
4. **Implementation Complexity**: Technical feasibility scoring 4. **Implementation Complexity**: Technical feasibility scoring
### Priority 2: Frontend Real-Time Integration (3 weeks) ### Priority 2: Frontend Real-Time Integration (3 weeks)
1. **WebSocket Client**: React hooks for WebSocket connections 1. **WebSocket Client**: React hooks for WebSocket connections
2. **Live Match Updates**: Real-time status indicators and notifications 2. **Live Match Updates**: Real-time status indicators and notifications
3. **Match Negotiation UI**: Interactive negotiation workflow 3. **Match Negotiation UI**: Interactive negotiation workflow
4. **Real-Time Dashboard**: Live economic impact calculations 4. **Real-Time Dashboard**: Live economic impact calculations
### Priority 3: Enhanced Features (2-3 weeks) ### Priority 3: Enhanced Features (2-3 weeks)
1. **Facilitator Entity**: External consultant marketplace 1. **Facilitator Entity**: External consultant marketplace
2. **Enhanced Resource Flows**: Detailed quality parameters and certifications 2. **Enhanced Resource Flows**: Detailed quality parameters and certifications
3. **Multi-Party Matching**: Complex supply chain optimization 3. **Multi-Party Matching**: Complex supply chain optimization
@ -371,6 +391,7 @@ ws.onmessage = (event) => {
## 🎯 **PRODUCTION READINESS** ## 🎯 **PRODUCTION READINESS**
### Current Status: **PRODUCTION READY** 🚀 ### Current Status: **PRODUCTION READY** 🚀
- ✅ **Database**: PostgreSQL + PostGIS (spatial operations) - ✅ **Database**: PostgreSQL + PostGIS (spatial operations)
- ✅ **Event Processing**: Redis Streams (optional, graceful degradation) - ✅ **Event Processing**: Redis Streams (optional, graceful degradation)
- ✅ **Real-Time**: WebSocket service for live updates - ✅ **Real-Time**: WebSocket service for live updates
@ -380,6 +401,7 @@ ws.onmessage = (event) => {
- ✅ **Performance**: <500ms match queries, <100ms economic calculations - ✅ **Performance**: <500ms match queries, <100ms economic calculations
### Deployment Ready Features: ### Deployment Ready Features:
- **Docker Support**: Containerized deployment - **Docker Support**: Containerized deployment
- **Environment Config**: 12-factor app configuration - **Environment Config**: 12-factor app configuration
- **Health Checks**: Service monitoring endpoints - **Health Checks**: Service monitoring endpoints
@ -401,6 +423,7 @@ ws.onmessage = (event) => {
## 🛠 **TECHNICAL STACK** ## 🛠 **TECHNICAL STACK**
### Backend ### Backend
- **Go 1.21+**: High-performance, type-safe backend - **Go 1.21+**: High-performance, type-safe backend
- **Gin**: Fast HTTP web framework - **Gin**: Fast HTTP web framework
- **GORM + PostgreSQL**: ORM with PostGIS spatial extensions - **GORM + PostgreSQL**: ORM with PostGIS spatial extensions
@ -409,6 +432,7 @@ ws.onmessage = (event) => {
- **JWT**: Secure authentication - **JWT**: Secure authentication
### Architecture Patterns ### Architecture Patterns
- **Clean Architecture**: Domain-driven design with clear boundaries - **Clean Architecture**: Domain-driven design with clear boundaries
- **Event-Driven**: Asynchronous processing with event sourcing - **Event-Driven**: Asynchronous processing with event sourcing
- **CQRS**: Separate read/write concerns (optional Neo4j for reads) - **CQRS**: Separate read/write concerns (optional Neo4j for reads)
@ -476,7 +500,7 @@ go run ./cmd/cli server
# Server available at http://localhost:8080 # Server available at http://localhost:8080
``` ```
**Default Admin**: `admin@tuganyak.dev` / `admin` **Default Admin**: `admin@turash.dev` / `admin`
## Technical Stack ## Technical Stack
@ -533,11 +557,13 @@ The Bugulma City Resource Graph backend is **fully implemented and production-re
- ✅ **Scalability**: Optimized queries and caching infrastructure - ✅ **Scalability**: Optimized queries and caching infrastructure
### ✅ Completed Production Enhancements (November 2025) ### ✅ Completed Production Enhancements (November 2025)
- **Redis Cache Implementation** - Full distributed caching with Redis SCAN invalidation - **Redis Cache Implementation** - Full distributed caching with Redis SCAN invalidation
- **JWT Authentication** - Production-ready JWT with custom claims and org awareness - **JWT Authentication** - Production-ready JWT with custom claims and org awareness
- **Event Context Enhancement** - Complete context extraction for all event publishing - **Event Context Enhancement** - Complete context extraction for all event publishing
### Minor Enhancements (Future Sprints) ### Minor Enhancements (Future Sprints)
- Enhanced analytics metrics (materials/energy/water tracking) - Enhanced analytics metrics (materials/energy/water tracking)
- Peer review scoring system - Peer review scoring system
- Advanced graph database operations - Advanced graph database operations

View File

@ -187,25 +187,25 @@ func runUserSetup(cmd *cobra.Command, args []string) error {
role domain.UserRole role domain.UserRole
}{ }{
{ {
email: "admin@tuganyak.dev", email: "admin@turash.dev",
name: "Admin User", name: "Admin User",
password: "admin123", password: "admin123",
role: domain.UserRoleAdmin, role: domain.UserRoleAdmin,
}, },
{ {
email: "user@tuganyak.dev", email: "user@turash.dev",
name: "Regular User", name: "Regular User",
password: "user123", password: "user123",
role: domain.UserRoleUser, role: domain.UserRoleUser,
}, },
{ {
email: "content@tuganyak.dev", email: "content@turash.dev",
name: "Content Manager", name: "Content Manager",
password: "content123", password: "content123",
role: domain.UserRoleContentManager, role: domain.UserRoleContentManager,
}, },
{ {
email: "viewer@tuganyak.dev", email: "viewer@turash.dev",
name: "Viewer User", name: "Viewer User",
password: "viewer123", password: "viewer123",
role: domain.UserRoleViewer, role: domain.UserRoleViewer,
@ -268,10 +268,10 @@ func runUserSetup(cmd *cobra.Command, args []string) error {
if !isQuiet() { if !isQuiet() {
fmt.Println("\nAll users setup complete!") fmt.Println("\nAll users setup complete!")
fmt.Println("\nLogin credentials:") fmt.Println("\nLogin credentials:")
fmt.Println(" Admin: admin@tuganyak.dev / admin123") fmt.Println(" Admin: admin@turash.dev / admin123")
fmt.Println(" User: user@tuganyak.dev / user123") fmt.Println(" User: user@turash.dev / user123")
fmt.Println(" Content Mgr: content@tuganyak.dev / content123") fmt.Println(" Content Mgr: content@turash.dev / content123")
fmt.Println(" Viewer: viewer@tuganyak.dev / viewer123") fmt.Println(" Viewer: viewer@turash.dev / viewer123")
} }
return nil return nil

View File

@ -0,0 +1,539 @@
package server
import (
"context"
"fmt"
"log"
"bugulma/backend/internal/analysis/regulatory"
"bugulma/backend/internal/analysis/risk"
"bugulma/backend/internal/analysis/transport"
"bugulma/backend/internal/domain"
"bugulma/backend/internal/financial"
"bugulma/backend/internal/geospatial"
"bugulma/backend/internal/graph"
"bugulma/backend/internal/handler"
"bugulma/backend/internal/matching"
"bugulma/backend/internal/middleware"
"bugulma/backend/internal/repository"
"bugulma/backend/internal/routes"
"bugulma/backend/internal/service"
"bugulma/backend/pkg/config"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
// StartServer initializes and starts the Bugulma backend server
func StartServer(port string) error {
// Load .env file
if err := godotenv.Load(); err != nil {
log.Printf("Warning: .env file not found, using environment variables")
}
// Load configuration
cfg := config.Load()
// Override port if provided
if port != "" {
cfg.ServerPort = port
}
// Initialize database
db, err := initializeDatabase(cfg)
if err != nil {
return fmt.Errorf("failed to initialize database: %w", err)
}
// Initialize repositories
userRepo, orgRepo, siteRepo, _, resourceFlowRepo, matchRepo, negotiationHistoryRepo, sharedAssetRepo, proposalRepo, geoFeatureRepo, productRepo, serviceRepo, communityListingRepo, publicTransportRepo := initializeRepositories(db)
// Seed default data
if err := seedDefaultData(userRepo); err != nil {
log.Printf("Warning: Failed to seed default data: %v", err)
}
// (Public transport seeding will occur after services are initialized)
// Initialize graph database (optional)
graphSyncService, graphHandler, graphTraversalHandler, orgGraphRepo, siteGraphRepo, addressGraphRepo, flowGraphRepo, matchGraphRepo, sharedAssetGraphRepo := initializeGraphDatabase(cfg)
// Initialize services
orgService, siteService, resourceFlowService, geospatialService, sharedAssetService, analyticsService, authService, matchingSvc, cacheService, websocketService, aiService, proposalService, spatialMatcher, environmentalSvc, facilityOptimizer, economicService, userService, adminService, i18nService, subscriptionService, verificationService, productRepo, serviceRepo, communityListingRepo, publicTransportService := initializeServices(
cfg, userRepo, orgRepo, siteRepo, resourceFlowRepo, matchRepo, negotiationHistoryRepo, sharedAssetRepo, proposalRepo, geoFeatureRepo,
orgGraphRepo, siteGraphRepo, addressGraphRepo, flowGraphRepo, matchGraphRepo, sharedAssetGraphRepo, db,
productRepo, serviceRepo, communityListingRepo,
)
// Store geographical services for future API endpoints
_ = spatialMatcher // Will be used in future API handlers
_ = environmentalSvc // Will be used in future API handlers
_ = facilityOptimizer // Will be used in future API handlers
// Seed public transport data (if repository and imported files present)
if publicTransportRepo != nil && publicTransportService != nil {
if err := service.ImportPublicTransportData(context.Background(), publicTransportService, publicTransportRepo); err != nil {
log.Printf("Warning: failed to import public transport data: %v", err)
}
}
// Set graph repositories on services that need them
if orgGraphRepo != nil {
orgService.SetGraphRepository(orgGraphRepo)
}
// Initialize GTFS repository and schedule service
gtfsRepo := repository.NewPublicTransportGTFSRepository(db)
scheduleService := service.NewScheduleService(gtfsRepo, publicTransportRepo)
// Initialize handlers (orgHandler is created inside initializeHandlers)
orgHandler, siteHandler, resourceFlowHandler, proposalHandler, matchingHandler, authHandler, sharedAssetHandler, geospatialHandler, analyticsHandler, aiHandler, heritageHandler, userHandler, orgAdminHandler, i18nHandler, contentHandler, adminHandler, subscriptionHandler, discoveryHandler, publicTransportHandler := initializeHandlers(
cfg, orgService, siteService, resourceFlowService, matchingSvc, authService, sharedAssetService, proposalService,
geospatialService, analyticsService, aiService, cacheService, db, userService, adminService, i18nService, subscriptionService, verificationService, publicTransportService, scheduleService,
)
// Setup router
router := setupRouter(authService)
// Initialize event-driven matching service with proper dependencies
// Note: eventBus is created in initializeServices, but we need to recreate it here for event-driven service
eventBus, err := service.NewRedisEventBus("redis://localhost:6379")
if err != nil {
log.Printf("Warning: Failed to create Redis event bus for event-driven matching: %v", err)
eventBus = nil
}
eventDrivenMatchingService := service.NewEventDrivenMatchingService(
eventBus, matchingSvc, resourceFlowRepo, matchRepo, websocketService.GetHub(), economicService,
)
if eventBus != nil {
if err := eventDrivenMatchingService.StartEventProcessing(context.Background()); err != nil {
log.Printf("Warning: Failed to start event-driven matching: %v", err)
}
}
// Setup routes
setupRoutes(router, orgHandler, siteHandler, resourceFlowHandler, proposalHandler, matchingHandler, authHandler,
sharedAssetHandler, geospatialHandler, analyticsHandler, aiHandler, heritageHandler, graphHandler,
graphTraversalHandler, websocketService, orgService, siteService, geospatialService, graphSyncService,
userHandler, orgAdminHandler, i18nHandler, contentHandler, adminHandler, subscriptionHandler, authService, discoveryHandler, publicTransportHandler)
// Start server
log.Printf("Server starting on port %s", cfg.ServerPort)
if err := router.Run(fmt.Sprintf(":%s", cfg.ServerPort)); err != nil {
return fmt.Errorf("failed to start server: %w", err)
}
return nil
}
// initializeDatabase sets up the database connection and runs migrations
func initializeDatabase(cfg *config.Config) (*gorm.DB, error) {
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
cfg.PostgresHost,
cfg.PostgresPort,
cfg.PostgresUser,
cfg.PostgresPassword,
cfg.PostgresDB,
cfg.PostgresSSLMode,
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("failed to connect to PostgreSQL: %w", err)
}
log.Println("Successfully connected to PostgreSQL database")
// Run PostGIS-specific migrations FIRST (before AutoMigrate)
if err := domain.RunPostGISMigrations(db); err != nil {
log.Printf("Warning: Failed to run PostGIS migrations: %v", err)
log.Println("Continuing without PostGIS spatial features")
} else {
log.Println("PostGIS migrations completed successfully")
}
// Run search migrations (pg_trgm extension and indexes)
if err := domain.RunSearchMigrations(db); err != nil {
log.Printf("Warning: Failed to run search migrations: %v", err)
log.Println("Continuing without fuzzy search features")
} else {
log.Println("Search migrations completed successfully")
}
// Auto-migrate database schema
if err := domain.AutoMigrate(db); err != nil {
return nil, fmt.Errorf("failed to migrate database: %w", err)
}
// Create additional indexes after AutoMigrate
if err := domain.CreateIndexes(db); err != nil {
log.Printf("Warning: Failed to create indexes: %v", err)
} else {
log.Println("Indexes created successfully")
}
log.Println("Database migration completed successfully")
return db, nil
}
// initializeRepositories creates all repository instances
func initializeRepositories(db *gorm.DB) (domain.UserRepository, domain.OrganizationRepository, domain.SiteRepository, domain.AddressRepository, domain.ResourceFlowRepository, domain.MatchRepository, domain.NegotiationHistoryRepository, domain.SharedAssetRepository, domain.ProposalRepository, domain.GeographicalFeatureRepository, domain.ProductRepository, domain.ServiceRepository, domain.CommunityListingRepository, domain.PublicTransportRepository) {
orgRepo := repository.NewOrganizationRepository(db)
siteRepo := repository.NewSiteRepository(db)
addressRepo := repository.NewAddressRepository(db)
resourceFlowRepo := repository.NewResourceFlowRepository(db)
matchRepo := repository.NewMatchRepository(db)
negotiationHistoryRepo := repository.NewNegotiationHistoryRepository(db)
sharedAssetRepo := repository.NewSharedAssetRepository(db)
proposalRepo := repository.NewProposalRepository(db)
userRepo := repository.NewUserRepository(db)
geoFeatureRepo := repository.NewGeographicalFeatureRepository(db)
productRepo := repository.NewProductRepository(db)
serviceRepo := repository.NewServiceRepository(db)
communityListingRepo := repository.NewCommunityListingRepository(db)
publicTransportRepo := repository.NewPublicTransportRepository(db)
_ = repository.NewResourceFlowVersionRepository(db)
return userRepo, orgRepo, siteRepo, addressRepo, resourceFlowRepo, matchRepo, negotiationHistoryRepo, sharedAssetRepo, proposalRepo, geoFeatureRepo, productRepo, serviceRepo, communityListingRepo, publicTransportRepo
}
// seedDefaultData seeds initial data like admin user
func seedDefaultData(userRepo domain.UserRepository) error {
_, err := userRepo.GetByEmail(context.Background(), "admin@turash.dev")
if err == nil {
return nil
}
adminUser := &domain.User{
ID: "admin-1",
Email: "admin@turash.dev",
Name: "Admin User",
Password: "$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", // "password" hashed with bcrypt
Role: domain.UserRoleAdmin,
}
return userRepo.Create(context.Background(), adminUser)
}
// initializeGraphDatabase initializes Neo4j graph database if enabled
func initializeGraphDatabase(cfg *config.Config) (*service.GraphSyncService, *handler.GraphHandler, *handler.GraphTraversalHandler, *repository.GraphOrganizationRepository, *repository.GraphSiteRepository, *repository.GraphAddressRepository, *repository.GraphResourceFlowRepository, *repository.GraphMatchRepository, *repository.GraphSharedAssetRepository) {
if !cfg.Neo4jEnabled {
return nil, nil, nil, nil, nil, nil, nil, nil, nil
}
neo4jURI := cfg.Neo4jURI
if neo4jURI == "" {
log.Println("Warning: Neo4j URI not configured, graph database disabled")
return nil, nil, nil, nil, nil, nil, nil, nil, nil
}
auth := neo4j.BasicAuth(cfg.Neo4jUsername, cfg.Neo4jPassword, "")
driver, err := neo4j.NewDriverWithContext(neo4jURI, auth)
if err != nil {
log.Printf("Warning: Failed to create Neo4j driver: %v", err)
log.Println("Continuing without graph database features")
return nil, nil, nil, nil, nil, nil, nil, nil, nil
}
// Verify connectivity
ctx := context.Background()
if err := driver.VerifyConnectivity(ctx); err != nil {
log.Printf("Warning: Failed to connect to Neo4j: %v", err)
log.Println("Continuing without graph database features")
return nil, nil, nil, nil, nil, nil, nil, nil, nil
}
log.Println("Successfully connected to Neo4j graph database")
// Initialize graph repositories
orgGraphRepo := repository.NewGraphOrganizationRepository(driver, cfg.Neo4jDatabase)
siteGraphRepo := repository.NewGraphSiteRepository(driver, cfg.Neo4jDatabase)
addressGraphRepo := repository.NewGraphAddressRepository(driver, cfg.Neo4jDatabase)
flowGraphRepo := repository.NewGraphResourceFlowRepository(driver, cfg.Neo4jDatabase)
matchGraphRepo := repository.NewGraphMatchRepository(driver, cfg.Neo4jDatabase)
sharedAssetGraphRepo := repository.NewGraphSharedAssetRepository(driver, cfg.Neo4jDatabase)
productGraphRepo := repository.NewGraphProductRepository(driver, cfg.Neo4jDatabase)
serviceGraphRepo := repository.NewGraphServiceRepository(driver, cfg.Neo4jDatabase)
// Initialize graph sync service
graphSyncService := service.NewGraphSyncService(
orgGraphRepo, siteGraphRepo, addressGraphRepo, flowGraphRepo,
matchGraphRepo, sharedAssetGraphRepo, productGraphRepo, serviceGraphRepo,
)
// Initialize graph calculator for traversal service
graphCalculator := graph.NewCalculatorWithDefaults(driver, cfg.Neo4jDatabase)
// Initialize services
graphTraversalService := service.NewGraphTraversalService(graphCalculator)
// Initialize handlers
graphHandler := handler.NewGraphHandler(driver, cfg.Neo4jDatabase, graphSyncService)
graphTraversalHandler := handler.NewGraphTraversalHandler(graphTraversalService)
return graphSyncService, graphHandler, graphTraversalHandler, orgGraphRepo, siteGraphRepo, addressGraphRepo, flowGraphRepo, matchGraphRepo, sharedAssetGraphRepo
}
// initializeServices creates all service instances
func initializeServices(
cfg *config.Config,
userRepo domain.UserRepository,
orgRepo domain.OrganizationRepository,
siteRepo domain.SiteRepository,
resourceFlowRepo domain.ResourceFlowRepository,
matchRepo domain.MatchRepository,
negotiationHistoryRepo domain.NegotiationHistoryRepository,
sharedAssetRepo domain.SharedAssetRepository,
proposalRepo domain.ProposalRepository,
geoFeatureRepo domain.GeographicalFeatureRepository,
orgGraphRepo *repository.GraphOrganizationRepository,
siteGraphRepo *repository.GraphSiteRepository,
addressGraphRepo *repository.GraphAddressRepository,
flowGraphRepo *repository.GraphResourceFlowRepository,
matchGraphRepo *repository.GraphMatchRepository,
sharedAssetGraphRepo *repository.GraphSharedAssetRepository,
db *gorm.DB,
productRepo domain.ProductRepository,
serviceRepo domain.ServiceRepository,
communityListingRepo domain.CommunityListingRepository,
) (*service.OrganizationService, *service.SiteService, *service.ResourceFlowService, *service.GeospatialService, *service.SharedAssetService, *service.AnalyticsService, *service.AuthService, *matching.Service, service.CacheService, *service.WebSocketService, *service.AIService, *service.ProposalService, *service.SpatialResourceMatcher, *service.EnvironmentalImpactService, *service.FacilityLocationOptimizer, *service.EconomicService, *service.UserService, *service.AdminService, *service.I18nService, *service.SubscriptionService, *service.VerificationService, domain.ProductRepository, domain.ServiceRepository, domain.CommunityListingRepository, *service.PublicTransportService) {
// Create event bus first
eventBus, err := service.NewRedisEventBus("redis://localhost:6379")
if err != nil {
log.Printf("Warning: Failed to create Redis event bus, using in-memory: %v", err)
eventBus = nil
}
// Create services
orgService := service.NewOrganizationService(orgRepo, nil) // Graph repo set later if available
siteService := service.NewSiteService(siteRepo)
resourceFlowService := service.NewResourceFlowService(resourceFlowRepo, eventBus)
authService := service.NewAuthService(userRepo, cfg.JWTSecret)
sharedAssetService := service.NewSharedAssetService(sharedAssetRepo)
geospatialService := service.NewGeospatialService(db, geoFeatureRepo)
analyticsService := service.NewAnalyticsService(db, orgRepo, siteRepo, resourceFlowRepo, matchRepo, sharedAssetRepo)
proposalService := service.NewProposalService(proposalRepo)
// Initialize geospatial calculator
geoCalc := geospatial.NewCalculatorWithDefaults()
// Initialize geographical transportation service
geoTransportSvc := service.NewTransportationService(geoCalc)
// Initialize geographical services
spatialMatcher := service.NewSpatialResourceMatcher(geoFeatureRepo, siteRepo, resourceFlowRepo, geospatialService, geoTransportSvc, geoCalc)
environmentalSvc := service.NewEnvironmentalImpactService(geoFeatureRepo, siteRepo, geospatialService, geoCalc)
facilityOptimizer := service.NewFacilityLocationOptimizer(geoFeatureRepo, siteRepo, geospatialService, spatialMatcher, environmentalSvc, geoTransportSvc)
// Create cache and websocket services
var cacheService service.CacheService
redisCache, err := service.NewRedisCacheService(cfg.RedisURL)
if err != nil {
log.Printf("Warning: Failed to initialize Redis cache, using in-memory cache: %v", err)
cacheService = service.NewMemoryCacheService()
} else {
log.Println("Successfully initialized Redis cache service")
cacheService = redisCache
}
websocketService := service.NewWebSocketService()
// Create analysis services for matching
riskSvc := risk.NewService()
transportSvc := transport.NewService()
regulatorySvc := regulatory.NewService()
// Create matching service
matchingSvc := matching.NewService(
matchRepo, negotiationHistoryRepo, resourceFlowRepo, siteRepo, orgRepo,
productRepo, serviceRepo, communityListingRepo,
riskSvc, transportSvc, regulatorySvc, eventBus,
)
// Create financial calculator and economic service
financialConfig := financial.DefaultConfig()
financialCalculator := financial.NewCalculator(financialConfig)
economicService := service.NewEconomicService(financialCalculator)
aiService := service.NewAIService()
// Create additional services needed by handlers
userService := service.NewUserService(userRepo)
// Create trust service
trustRepo := repository.NewTrustMetricsRepository(db)
verifiedRepo := repository.NewVerifiedDataRepository(db)
historicalRepo := repository.NewHistoricalSuccessRepository(db)
trustService := service.NewTrustService(trustRepo, verifiedRepo, historicalRepo)
// Create i18n service - simplified initialization
locRepo := repository.NewLocalizationRepository(db)
i18nService := service.NewI18nService(nil, locRepo, nil, nil) // Simplified - can be enhanced later
// Create subscription service
subscriptionRepo := repository.NewSubscriptionRepository(db)
// UsageTrackingRepository can be nil for now - create if needed later
subscriptionService := service.NewSubscriptionService(subscriptionRepo, nil, userRepo)
// Create verification service
verificationService := service.NewVerificationService(trustService, orgService)
// Create admin service
adminService := service.NewAdminService(orgService, userService, verificationService, i18nService)
// Initialize public transport service (reads data/bugulma_public_transport_enriched.json if available)
publicTransportService, err := service.NewPublicTransportService("data")
if err != nil {
log.Printf("Warning: failed to initialize public transport service: %v", err)
publicTransportService = nil
}
return orgService, siteService, resourceFlowService, geospatialService, sharedAssetService, analyticsService, authService, matchingSvc, cacheService, websocketService, aiService, proposalService, spatialMatcher, environmentalSvc, facilityOptimizer, economicService, userService, adminService, i18nService, subscriptionService, verificationService, productRepo, serviceRepo, communityListingRepo, publicTransportService
}
// initializeHandlers creates all HTTP handler instances
func initializeHandlers(
cfg *config.Config,
orgService *service.OrganizationService,
siteService *service.SiteService,
resourceFlowService *service.ResourceFlowService,
matchingSvc *matching.Service,
authService *service.AuthService,
sharedAssetService *service.SharedAssetService,
proposalService *service.ProposalService,
geospatialService *service.GeospatialService,
analyticsService *service.AnalyticsService,
aiService *service.AIService,
cacheService service.CacheService,
db *gorm.DB,
userService *service.UserService,
adminService *service.AdminService,
i18nService *service.I18nService,
subscriptionService *service.SubscriptionService,
verificationService *service.VerificationService,
publicTransportService *service.PublicTransportService,
scheduleService *service.ScheduleService,
) (*handler.OrganizationHandler, *handler.SiteHandler, *handler.ResourceFlowHandler, *handler.ProposalHandler, *handler.MatchingHandler, *handler.AuthHandler, *handler.SharedAssetHandler, *handler.GeospatialHandler, *handler.AnalyticsHandler, *handler.AIHandler, *handler.HeritageHandler, *handler.UserHandler, *handler.OrganizationAdminHandler, *handler.I18nHandler, *handler.ContentHandler, *handler.AdminHandler, *handler.SubscriptionHandler, *handler.DiscoveryHandler, *handler.PublicTransportHandler) {
imageService := service.NewImageService(cfg)
orgHandler := handler.NewOrganizationHandler(orgService, imageService, resourceFlowService, matchingSvc, proposalService)
siteHandler := handler.NewSiteHandler(siteService)
resourceFlowHandler := handler.NewResourceFlowHandler(resourceFlowService)
proposalHandler := handler.NewProposalHandler(proposalService)
matchingHandler := handler.NewMatchingHandler(matchingSvc, nil)
authHandler := handler.NewAuthHandler(authService)
sharedAssetHandler := handler.NewSharedAssetHandler(sharedAssetService)
geospatialHandler := handler.NewGeospatialHandler(geospatialService)
analyticsHandler := handler.NewAnalyticsHandler(analyticsService)
aiHandler := handler.NewAIHandler(aiService)
heritageHandler := handler.NewHeritageHandler(repository.NewHeritageRepository(db))
// Additional handlers
userHandler := handler.NewUserHandler(userService)
orgAdminHandler := handler.NewOrganizationAdminHandler(orgHandler, verificationService)
i18nHandler := handler.NewI18nHandler(i18nService)
contentHandler := handler.NewContentHandler(service.NewContentService(
repository.NewStaticPageRepository(db),
repository.NewAnnouncementRepository(db),
repository.NewMediaAssetRepository(db),
))
adminHandler := handler.NewAdminHandler(adminService)
subscriptionHandler := handler.NewSubscriptionHandler(subscriptionService)
discoveryHandler := handler.NewDiscoveryHandler(matchingSvc)
publicTransportHandler := handler.NewPublicTransportHandler(publicTransportService, scheduleService)
return orgHandler, siteHandler, resourceFlowHandler, proposalHandler, matchingHandler, authHandler, sharedAssetHandler, geospatialHandler, analyticsHandler, aiHandler, heritageHandler, userHandler, orgAdminHandler, i18nHandler, contentHandler, adminHandler, subscriptionHandler, discoveryHandler, publicTransportHandler
}
// setupRouter configures the Gin router with middleware
func setupRouter(authService *service.AuthService) *gin.Engine {
router := gin.Default()
// Serve static files
router.Static("/static", "./static")
// CORS middleware
router.Use(func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
// Context middleware for extracting user/org info from JWT or headers
router.Use(middleware.ContextMiddleware(authService))
return router
}
// setupRoutes configures all API routes using the organized routes package
func setupRoutes(
router *gin.Engine,
orgHandler *handler.OrganizationHandler,
siteHandler *handler.SiteHandler,
resourceHandler *handler.ResourceFlowHandler,
proposalHandler *handler.ProposalHandler,
matchingHandler *handler.MatchingHandler,
authHandler *handler.AuthHandler,
sharedAssetHandler *handler.SharedAssetHandler,
geospatialHandler *handler.GeospatialHandler,
analyticsHandler *handler.AnalyticsHandler,
aiHandler *handler.AIHandler,
heritageHandler *handler.HeritageHandler,
graphHandler *handler.GraphHandler,
graphTraversalHandler *handler.GraphTraversalHandler,
websocketService *service.WebSocketService,
orgService *service.OrganizationService,
siteService *service.SiteService,
geospatialService *service.GeospatialService,
graphSyncService *service.GraphSyncService,
userHandler *handler.UserHandler,
orgAdminHandler *handler.OrganizationAdminHandler,
i18nHandler *handler.I18nHandler,
contentHandler *handler.ContentHandler,
adminHandler *handler.AdminHandler,
subscriptionHandler *handler.SubscriptionHandler,
authService *service.AuthService,
discoveryHandler *handler.DiscoveryHandler,
publicTransportHandler *handler.PublicTransportHandler,
) {
routes.RegisterAllRoutes(
router,
orgHandler,
siteHandler,
resourceHandler,
proposalHandler,
matchingHandler,
authHandler,
sharedAssetHandler,
geospatialHandler,
analyticsHandler,
aiHandler,
heritageHandler,
graphHandler,
graphTraversalHandler,
websocketService,
userHandler,
orgAdminHandler,
i18nHandler,
contentHandler,
adminHandler,
subscriptionHandler,
authService,
discoveryHandler,
publicTransportHandler,
)
}

View File

@ -242,7 +242,7 @@ CREATE (s3)-[:HOSTS]->(r3);
// Create admin user // Create admin user
CREATE (u1:User { CREATE (u1:User {
id: "user-admin", id: "user-admin",
email: "admin@tuganyak.dev", email: "admin@turash.dev",
password_hash: "$2a$10$example.hash.for.demo.purposes.only", password_hash: "$2a$10$example.hash.for.demo.purposes.only",
role: "admin", role: "admin",
created_at: datetime(), created_at: datetime(),

View File

@ -3,25 +3,29 @@
This document contains the login credentials for test users with different roles. This document contains the login credentials for test users with different roles.
## Admin User ## Admin User
- **Email**: `admin@tuganyak.dev`
- **Email**: `admin@turash.dev`
- **Password**: `admin123` - **Password**: `admin123`
- **Role**: `admin` - **Role**: `admin`
- **Access**: Full admin panel access - **Access**: Full admin panel access
## Regular User ## Regular User
- **Email**: `user@tuganyak.dev`
- **Email**: `user@turash.dev`
- **Password**: `user12345` - **Password**: `user12345`
- **Role**: `user` - **Role**: `user`
- **Access**: Regular user dashboard - **Access**: Regular user dashboard
## Content Manager ## Content Manager
- **Email**: `content@tuganyak.dev`
- **Email**: `content@turash.dev`
- **Password**: `content123` - **Password**: `content123`
- **Role**: `content_manager` - **Role**: `content_manager`
- **Access**: Content and localization management - **Access**: Content and localization management
## Viewer ## Viewer
- **Email**: `viewer@tuganyak.dev`
- **Email**: `viewer@turash.dev`
- **Password**: `viewer123` - **Password**: `viewer123`
- **Role**: `viewer` - **Role**: `viewer`
- **Access**: Read-only access - **Access**: Read-only access
@ -32,4 +36,3 @@ This document contains the login credentials for test users with different roles
- To update a user's role, use the admin API endpoint: `PATCH /api/v1/admin/users/:id/role` - To update a user's role, use the admin API endpoint: `PATCH /api/v1/admin/users/:id/role`
- Or update directly in the database: `UPDATE users SET role = 'admin' WHERE email = 'user@example.com';` - Or update directly in the database: `UPDATE users SET role = 'admin' WHERE email = 'user@example.com';`
- After updating a role in the database, the user needs to log out and log back in to refresh their JWT token - After updating a role in the database, the user needs to log out and log back in to refresh their JWT token

View File

@ -11,7 +11,7 @@ SELECT id, email, name, role, is_active FROM users;
-- Update existing admin user to ensure it has admin role -- Update existing admin user to ensure it has admin role
UPDATE users UPDATE users
SET role = 'admin', is_active = true SET role = 'admin', is_active = true
WHERE email = 'admin@tuganyak.dev'; WHERE email = 'admin@turash.dev';
-- Create/update users for each role -- Create/update users for each role
-- Note: These passwords need to be hashed with bcrypt before inserting -- Note: These passwords need to be hashed with bcrypt before inserting

View File

@ -1,5 +1,5 @@
import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
import { login as apiLogin, signup as apiSignup } from '@/lib/api-client'; import { login as apiLogin, signup as apiSignup } from '@/lib/api-client';
import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
export type UserRole = 'admin' | 'user' | 'content_manager' | 'viewer'; export type UserRole = 'admin' | 'user' | 'content_manager' | 'viewer';
@ -45,13 +45,13 @@ function extractUserFromToken(token: string): User | null {
try { try {
// Only extract basic info for UI - never trust this data for security decisions // Only extract basic info for UI - never trust this data for security decisions
const payload = JSON.parse(atob(token.split('.')[1])); const payload = JSON.parse(atob(token.split('.')[1]));
return { return {
id: payload.sub || payload.id || '1', id: payload.sub || payload.id || '1',
email: payload.email || 'user@tuganyak.dev', email: payload.email || 'user@turash.dev',
name: payload.name || payload.firstName || 'User', name: payload.name || payload.firstName || 'User',
role: (payload.role || 'user') as UserRole, role: (payload.role || 'user') as UserRole,
permissions: payload.permissions, permissions: payload.permissions,
}; };
} catch { } catch {
return null; return null;
} }
@ -66,11 +66,12 @@ async function validateTokenServerSide(token: string): Promise<User | null> {
// Make an authenticated request to validate the token // Make an authenticated request to validate the token
// Using a lightweight endpoint to check token validity // Using a lightweight endpoint to check token validity
const isProduction = import.meta.env.PROD; const isProduction = import.meta.env.PROD;
const baseUrl = import.meta.env.VITE_API_BASE_URL || (isProduction ? 'https://api.bugulma.city' : ''); const baseUrl =
import.meta.env.VITE_API_BASE_URL || (isProduction ? 'https://api.bugulma.city' : '');
const response = await fetch(`${baseUrl}/api/v1/auth/me`, { const response = await fetch(`${baseUrl}/api/v1/auth/me`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Authorization': `Bearer ${token}`, Authorization: `Bearer ${token}`,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
// Add timeout to prevent hanging requests // Add timeout to prevent hanging requests

View File

@ -5,7 +5,7 @@ export const en = {
tt: 'TT', tt: 'TT',
}, },
topBar: { topBar: {
title: 'Tugan Yak', title: 'Turash',
subTitle: 'Bugulma Ecosystem', subTitle: 'Bugulma Ecosystem',
loginButton: 'Login', loginButton: 'Login',
adminButton: 'Admin', adminButton: 'Admin',
@ -283,7 +283,7 @@ export const en = {
ctaNote: 'Available only to authorized users.', ctaNote: 'Available only to authorized users.',
}, },
footer: { footer: {
copyright: '© {{year}} Tugan Yak. All rights reserved.', copyright: '© {{year}} Turash. All rights reserved.',
links: { links: {
about: 'About', about: 'About',
contact: 'Contact', contact: 'Contact',
@ -324,9 +324,9 @@ export const en = {
}, },
}, },
chatbot: { chatbot: {
header: 'Tugan Yak AI', header: 'Turash AI',
online: 'Online', online: 'Online',
initialMessage: 'Hello! I am your assistant for the "Tugan Yak" ecosystem. How can I help you?', initialMessage: 'Hello! I am your assistant for the "Turash" ecosystem. How can I help you?',
placeholder: 'Ask something...', placeholder: 'Ask something...',
sendLabel: 'Send', sendLabel: 'Send',
closeLabel: 'Close chat', closeLabel: 'Close chat',
@ -542,7 +542,7 @@ export const en = {
}, },
adminPage: { adminPage: {
title: 'Admin Panel', title: 'Admin Panel',
subtitle: 'Overview and management of the "Tugan Yak" ecosystem', subtitle: 'Overview and management of the "Turash" ecosystem',
totalOrgs: 'Total Organizations', totalOrgs: 'Total Organizations',
verifiedOrgs: 'Verified', verifiedOrgs: 'Verified',
connections: 'Symbiotic Links', connections: 'Symbiotic Links',
@ -701,10 +701,10 @@ export const en = {
}, },
}, },
aboutPage: { aboutPage: {
p1: 'The "Tugan Yak" project is a digital platform created to visualize and strengthen economic ties within the city of Bugulma.', p1: 'The "Turash" project is a digital platform created to visualize and strengthen economic ties within the city of Bugulma.',
p2: 'Our goal is to promote industrial symbiosis, where the waste of one enterprise becomes a raw material for another. This not only reduces costs for businesses but also improves the environmental situation in the region.', p2: 'Our goal is to promote industrial symbiosis, where the waste of one enterprise becomes a raw material for another. This not only reduces costs for businesses but also improves the environmental situation in the region.',
p3: 'Using modern technologies, including artificial intelligence, we help companies find new partners, optimize logistics, and discover non-obvious opportunities for cooperation.', p3: 'Using modern technologies, including artificial intelligence, we help companies find new partners, optimize logistics, and discover non-obvious opportunities for cooperation.',
p4: 'We believe that a strong local economy is built on strong connections. "Tugan Yak" is our contribution to the prosperity of our native land.', p4: 'We believe that a strong local economy is built on strong connections. "Turash" is our contribution to the prosperity of our native land.',
}, },
contactPage: { contactPage: {
lead: 'We are always open to suggestions and collaboration. Contact us in any convenient way.', lead: 'We are always open to suggestions and collaboration. Contact us in any convenient way.',
@ -717,7 +717,7 @@ export const en = {
email: { email: {
title: 'Email', title: 'Email',
line1: 'For general questions and suggestions', line1: 'For general questions and suggestions',
line2: 'info@tuganyak.dev', line2: 'info@turash.dev',
}, },
phone: { title: 'Phone', line1: 'Support and consultations', line2: '+7 (855) 941-23-45' }, phone: { title: 'Phone', line1: 'Support and consultations', line2: '+7 (855) 941-23-45' },
}, },
@ -728,7 +728,7 @@ export const en = {
{ {
title: '1. General Provisions', title: '1. General Provisions',
content: content:
'This personal data processing policy has been compiled in accordance with the requirements of the Federal Law of 27.07.2006. No. 152-FZ "On Personal Data" and determines the procedure for processing personal data and measures to ensure the security of personal data undertaken by the "Tugan Yak" project.', 'This personal data processing policy has been compiled in accordance with the requirements of the Federal Law of 27.07.2006. No. 152-FZ "On Personal Data" and determines the procedure for processing personal data and measures to ensure the security of personal data undertaken by the "Turash" project.',
}, },
{ {
title: '2. Basic concepts used in the Policy', title: '2. Basic concepts used in the Policy',
@ -820,7 +820,7 @@ export const en = {
instruction: 'Write a narrative paragraph about this landmark.', instruction: 'Write a narrative paragraph about this landmark.',
}, },
chatSystemInstruction: chatSystemInstruction:
'You are a helpful AI assistant for the "Tugan Yak" platform. Your name is Tugan Yak AI. Your goal is to help users find information about local businesses, services, and cooperation opportunities within the city of Bugulma. If an image is provided, analyze it in the context of the user\'s question. Use the metaphor of a "compass" or "navigator" to guide users. Be concise, friendly, and focus on providing actionable information relevant to the Tugan Yak platform for industrial symbiosis. Format your responses using basic markdown (bolding with ** and unordered lists with *).', 'You are a helpful AI assistant for the "Turash" platform. Your name is Turash AI. Your goal is to help users find information about local businesses, services, and cooperation opportunities within the city of Bugulma. If an image is provided, analyze it in the context of the user\'s question. Use the metaphor of a "compass" or "navigator" to guide users. Be concise, friendly, and focus on providing actionable information relevant to the Turash platform for industrial symbiosis. Format your responses using basic markdown (bolding with ** and unordered lists with *).',
}, },
validation: { validation: {
string: { string: {
@ -1123,6 +1123,9 @@ export const en = {
dashboard: { dashboard: {
title: 'Dashboard', title: 'Dashboard',
subtitle: 'Welcome back, {{name}}!', subtitle: 'Welcome back, {{name}}!',
noRecentActivityTitle: 'No Recent Activity',
noRecentActivityDesc:
'Recent activity will appear here as organizations interact on the platform',
organizations: 'Organizations', organizations: 'Organizations',
sites: 'Sites', sites: 'Sites',
resourceFlows: 'Resource Flows', resourceFlows: 'Resource Flows',
@ -1153,6 +1156,18 @@ export const en = {
matchSuccessRate: 'Match Success Rate', matchSuccessRate: 'Match Success Rate',
avgMatchTime: 'Avg Match Time (days)', avgMatchTime: 'Avg Match Time (days)',
activeResourceTypes: 'Active Resource Types', activeResourceTypes: 'Active Resource Types',
yourContribution: 'Your Contribution',
yourContributionDesc: 'Track your impact on the platform',
myProposals: 'My Proposals',
myPendingProposals: 'Pending Proposals',
platformOverview: 'Platform Overview',
platformOverviewDesc: 'Key metrics and activities',
filterAll: 'All',
filterMatches: 'Matches',
filterProposals: 'Proposals',
filterOrganizations: 'Organizations',
noActiveProposalsTitle: 'No Active Proposals',
noActiveProposalsDesc: "You don't have any active proposals at the moment",
}, },
analyticsDashboard: { analyticsDashboard: {
title: 'Analytics Dashboard', title: 'Analytics Dashboard',
@ -1254,9 +1269,11 @@ export const en = {
addressShortages: 'Address Shortages', addressShortages: 'Address Shortages',
shortageRecommendation: 'Focus on increasing supply for high-demand resources with shortages.', shortageRecommendation: 'Focus on increasing supply for high-demand resources with shortages.',
optimizeSurplus: 'Optimize Surplus', optimizeSurplus: 'Optimize Surplus',
surplusRecommendation: 'Connect surplus resources with potential users to maximize utilization.', surplusRecommendation:
'Connect surplus resources with potential users to maximize utilization.',
monitorTrends: 'Monitor Trends', monitorTrends: 'Monitor Trends',
monitoringRecommendation: 'Continue monitoring supply/demand trends to identify emerging opportunities.', monitoringRecommendation:
'Continue monitoring supply/demand trends to identify emerging opportunities.',
noAnalysisData: 'No supply/demand analysis data available', noAnalysisData: 'No supply/demand analysis data available',
}, },
organizationCard: { organizationCard: {
@ -1447,4 +1464,11 @@ export const en = {
need: 'Need', need: 'Need',
}, },
}, },
dateRange: {
last7Days: 'Last 7 Days',
last30Days: 'Last 30 Days',
last90Days: 'Last 90 Days',
lastYear: 'Last Year',
allTime: 'All Time',
},
}; };

View File

@ -5,7 +5,7 @@ export const ru = {
tt: 'TT', tt: 'TT',
}, },
topBar: { topBar: {
title: 'Туган Як', title: 'Turash',
subTitle: 'Экосистема г. Бугульма', subTitle: 'Экосистема г. Бугульма',
loginButton: 'Войти', loginButton: 'Войти',
adminButton: 'Админ', adminButton: 'Админ',
@ -284,7 +284,7 @@ export const ru = {
ctaNote: 'Доступно только для авторизованных пользователей.', ctaNote: 'Доступно только для авторизованных пользователей.',
}, },
footer: { footer: {
copyright: '© {{year}} Туган Як. Все права защищены.', copyright: '© {{year}} Turash. Все права защищены.',
links: { links: {
about: 'О проекте', about: 'О проекте',
contact: 'Контакты', contact: 'Контакты',
@ -325,9 +325,9 @@ export const ru = {
}, },
}, },
chatbot: { chatbot: {
header: 'Туган Як AI', header: 'Turash AI',
online: 'Онлайн', online: 'Онлайн',
initialMessage: 'Здравствуйте! Я — ваш помощник по экосистеме "Туган Як". Чем могу помочь?', initialMessage: 'Здравствуйте! Я — ваш помощник по экосистеме "Turash". Чем могу помочь?',
placeholder: 'Спросите что-нибудь...', placeholder: 'Спросите что-нибудь...',
sendLabel: 'Отправить', sendLabel: 'Отправить',
closeLabel: 'Закрыть чат', closeLabel: 'Закрыть чат',
@ -541,7 +541,7 @@ export const ru = {
}, },
adminPage: { adminPage: {
title: 'Панель администратора', title: 'Панель администратора',
subtitle: 'Обзор и управление экосистемой "Туган Як"', subtitle: 'Обзор и управление экосистемой "Turash"',
totalOrgs: 'Всего организаций', totalOrgs: 'Всего организаций',
verifiedOrgs: 'Проверенных', verifiedOrgs: 'Проверенных',
connections: 'Симбиотических связей', connections: 'Симбиотических связей',
@ -573,10 +573,10 @@ export const ru = {
}, },
}, },
aboutPage: { aboutPage: {
p1: 'Проект "Туган Як" — это цифровая платформа, созданная для визуализации и укрепления экономических связей внутри города Бугульма.', p1: 'Проект "Turash" — это цифровая платформа, созданная для визуализации и укрепления экономических связей внутри города Бугульма.',
p2: 'Наша цель — способствовать развитию промышленного симбиоза, где отходы одного предприятия становятся сырьем для другого. Это не только снижает издержки для бизнеса, но и улучшает экологическую обстановку в регионе.', p2: 'Наша цель — способствовать развитию промышленного симбиоза, где отходы одного предприятия становятся сырьем для другого. Это не только снижает издержки для бизнеса, но и улучшает экологическую обстановку в регионе.',
p3: 'Используя современные технологии, включая искусственный интеллект, мы помогаем компаниям находить новых партнеров, оптимизировать логистику и открывать не очевидные возможности для сотрудничества.', p3: 'Используя современные технологии, включая искусственный интеллект, мы помогаем компаниям находить новых партнеров, оптимизировать логистику и открывать не очевидные возможности для сотрудничества.',
p4: 'Мы верим, что сильная местная экономика строится на прочных связях. "Туган Як" — это наш вклад в процветание родного края.', p4: 'Мы верим, что сильная местная экономика строится на прочных связях. "Turash" — это наш вклад в процветание родного края.',
}, },
contactPage: { contactPage: {
lead: 'Мы всегда открыты для предложений и сотрудничества. Свяжитесь с нами любым удобным способом.', lead: 'Мы всегда открыты для предложений и сотрудничества. Свяжитесь с нами любым удобным способом.',
@ -589,7 +589,7 @@ export const ru = {
email: { email: {
title: 'Электронная почта', title: 'Электронная почта',
line1: 'Для общих вопросов и предложений', line1: 'Для общих вопросов и предложений',
line2: 'info@tuganyak.dev', line2: 'info@turash.dev',
}, },
phone: { title: 'Телефон', line1: 'Поддержка и консультации', line2: '+7 (855) 941-23-45' }, phone: { title: 'Телефон', line1: 'Поддержка и консультации', line2: '+7 (855) 941-23-45' },
}, },
@ -600,7 +600,7 @@ export const ru = {
{ {
title: '1. Общие положения', title: '1. Общие положения',
content: content:
'Настоящая политика обработки персональных данных составлена в соответствии с требованиями Федерального закона от 27.07.2006. №152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые проектом "Туган Як".', 'Настоящая политика обработки персональных данных составлена в соответствии с требованиями Федерального закона от 27.07.2006. №152-ФЗ «О персональных данных» и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые проектом "Turash".',
}, },
{ {
title: '2. Основные понятия, используемые в Политике', title: '2. Основные понятия, используемые в Политике',
@ -693,7 +693,7 @@ export const ru = {
instruction: 'Напишите повествовательный абзац об этом памятнике.', instruction: 'Напишите повествовательный абзац об этом памятнике.',
}, },
chatSystemInstruction: chatSystemInstruction:
'Вы — полезный AI-ассистент для платформы "Туган Як". Ваше имя — Туган Як AI. Ваша цель — помогать пользователям находить информацию о местных предприятиях, услугах и возможностях сотрудничества в городе Бугульма. Если предоставлено изображение, проанализируйте его в контексте вопроса пользователя. Используйте метафору "компаса" или "навигатора", чтобы направлять пользователей. Будьте краткими, дружелюбными и сосредоточьтесь на предоставлении действенной информации, relevantной для платформы промышленного симбиоза "Туган Як". Форматируйте свои ответы, используя базовый markdown (выделение жирным с помощью ** и неупорядоченные списки с помощью *).', 'Вы — полезный AI-ассистент для платформы "Turash". Ваше имя — Turash AI. Ваша цель — помогать пользователям находить информацию о местных предприятиях, услугах и возможностях сотрудничества в городе Бугульма. Если предоставлено изображение, проанализируйте его в контексте вопроса пользователя. Используйте метафору "компаса" или "навигатора", чтобы направлять пользователей. Будьте краткими, дружелюбными и сосредоточьтесь на предоставлении действенной информации, relevantной для платформы промышленного симбиоза "Turash". Форматируйте свои ответы, используя базовый markdown (выделение жирным с помощью ** и неупорядоченные списки с помощью *).',
}, },
validation: { validation: {
string: { string: {

View File

@ -5,7 +5,7 @@ export const tt = {
tt: 'TT', tt: 'TT',
}, },
topBar: { topBar: {
title: 'Туган Як', title: 'Turash',
subTitle: 'Бөгелмә шәһәре экосистемасы', subTitle: 'Бөгелмә шәһәре экосистемасы',
loginButton: 'Керү', loginButton: 'Керү',
adminButton: 'Админ', adminButton: 'Админ',
@ -269,7 +269,7 @@ export const tt = {
ctaNote: 'Бары тик авторизацияләнгән кулланучылар өчен генә мөмкин.', ctaNote: 'Бары тик авторизацияләнгән кулланучылар өчен генә мөмкин.',
}, },
footer: { footer: {
copyright: '© {{year}} Туган Як. Барлык хокуклар сакланган.', copyright: '© {{year}} Turash. Барлык хокуклар сакланган.',
links: { links: {
about: 'Проект турында', about: 'Проект турында',
contact: 'Контактлар', contact: 'Контактлар',
@ -310,10 +310,10 @@ export const tt = {
}, },
}, },
chatbot: { chatbot: {
header: 'Туган Як AI', header: 'Turash AI',
online: 'Онлайн', online: 'Онлайн',
initialMessage: initialMessage:
'Исәнмесез! Мин - "Туган Як" экосистемасы буенча сезнең ярдәмчегез. Нәрсә белән ярдәм итә алам?', 'Исәнмесез! Мин - "Turash" экосистемасы буенча сезнең ярдәмчегез. Нәрсә белән ярдәм итә алам?',
placeholder: 'Берәр нәрсә сорагыз...', placeholder: 'Берәр нәрсә сорагыз...',
sendLabel: 'Җибәрү', sendLabel: 'Җибәрү',
closeLabel: 'Чатны ябу', closeLabel: 'Чатны ябу',
@ -518,7 +518,7 @@ export const tt = {
}, },
adminPage: { adminPage: {
title: 'Администратор панеле', title: 'Администратор панеле',
subtitle: '"Туган Як" экосистемасын күзәтү һәм идарә итү', subtitle: '"Turash" экосистемасын күзәтү һәм идарә итү',
totalOrgs: 'Барлык оешмалар', totalOrgs: 'Барлык оешмалар',
verifiedOrgs: 'Тикшерелгәннәр', verifiedOrgs: 'Тикшерелгәннәр',
connections: 'Симбиотик бәйләнешләр', connections: 'Симбиотик бәйләнешләр',
@ -550,10 +550,10 @@ export const tt = {
}, },
}, },
aboutPage: { aboutPage: {
p1: '"Туган Як" проекты — Бөгелмә шәһәре эчендә икътисади элемтәләрне визуальләштерү һәм ныгыту өчен булдырылган санлы платформа.', p1: '"Turash" проекты — Бөгелмә шәһәре эчендә икътисади элемтәләрне визуальләштерү һәм ныгыту өчен булдырылган санлы платформа.',
p2: 'Безнең максат — сәнәгый симбиоз үсешенә булышлык итү, анда бер предприятиенең калдыклары икенчесе өчен чимал була. Бу бизнес өчен чыгымнарны киметә генә түгел, ә регионда экологик хәлне дә яхшырта.', p2: 'Безнең максат — сәнәгый симбиоз үсешенә булышлык итү, анда бер предприятиенең калдыклары икенчесе өчен чимал була. Бу бизнес өчен чыгымнарны киметә генә түгел, ә регионда экологик хәлне дә яхшырта.',
p3: 'Ясалма интеллект кебек заманча технологияләрне кулланып, без компанияләргә яңа партнерлар табарга, логистиканы оптимальләштерергә һәм хезмәттәшлек өчен ачык булмаган мөмкинлекләр ачарга ярдәм итәбез.', p3: 'Ясалма интеллект кебек заманча технологияләрне кулланып, без компанияләргә яңа партнерлар табарга, логистиканы оптимальләштерергә һәм хезмәттәшлек өчен ачык булмаган мөмкинлекләр ачарга ярдәм итәбез.',
p4: 'Без ышанабыз, көчле җирле икътисад ныклы элемтәләрдә төзелә. "Туган Як" — туган ягыбызның чәчәк атуына безнең өлешебез.', p4: 'Без ышанабыз, көчле җирле икътисад ныклы элемтәләрдә төзелә. "Turash" — туган ягыбызның чәчәк атуына безнең өлешебез.',
}, },
contactPage: { contactPage: {
lead: 'Без һәрвакыт тәкъдимнәргә һәм хезмәттәшлеккә ачык. Безнең белән теләсә кайсы уңайлы ысул белән элемтәгә керегез.', lead: 'Без һәрвакыт тәкъдимнәргә һәм хезмәттәшлеккә ачык. Безнең белән теләсә кайсы уңайлы ысул белән элемтәгә керегез.',
@ -566,7 +566,7 @@ export const tt = {
email: { email: {
title: 'Электрон почта', title: 'Электрон почта',
line1: 'Гомуми сораулар һәм тәкъдимнәр өчен', line1: 'Гомуми сораулар һәм тәкъдимнәр өчен',
line2: 'info@tuganyak.dev', line2: 'info@turash.dev',
}, },
phone: { title: 'Телефон', line1: 'Ярдәм һәм консультацияләр', line2: '+7 (855) 941-23-45' }, phone: { title: 'Телефон', line1: 'Ярдәм һәм консультацияләр', line2: '+7 (855) 941-23-45' },
}, },
@ -577,7 +577,7 @@ export const tt = {
{ {
title: '1. Гомуми нигезләмәләр', title: '1. Гомуми нигезләмәләр',
content: content:
'Бу шәхси мәгълүматларны эшкәртү сәясәте 27.07.2006 елгы №152-ФЗ «Шәхси мәгълүматлар турында» Федераль закон таләпләренә туры китереп төзелгән һәм "Туган Як" проекты тарафыннан шәхси мәгълүматларны эшкәртү тәртибен һәм шәхси мәгълүматларның куркынычсызлыгын тәэмин итү чараларын билгели.', 'Бу шәхси мәгълүматларны эшкәртү сәясәте 27.07.2006 елгы №152-ФЗ «Шәхси мәгълүматлар турында» Федераль закон таләпләренә туры китереп төзелгән һәм "Turash" проекты тарафыннан шәхси мәгълүматларны эшкәртү тәртибен һәм шәхси мәгълүматларның куркынычсызлыгын тәэмин итү чараларын билгели.',
}, },
{ {
title: '2. Сәясәттә кулланылган төп төшенчәләр', title: '2. Сәясәттә кулланылган төп төшенчәләр',
@ -663,11 +663,12 @@ export const tt = {
instruction: 'Бу һәйкәл турында хикәяләү абзацы языгыз.', instruction: 'Бу һәйкәл турында хикәяләү абзацы языгыз.',
}, },
chatSystemInstruction: chatSystemInstruction:
'Сез — "Туган Як" платформасы өчен файдалы ЯИ-ярдәмче. Сезнең исемегез — Туган Як ЯИ. Сезнең максат — кулланучыларга Бөгелмә шәһәрендәге җирле предприятиеләр, хезмәтләр һәм хезмәттәшлек мөмкинлекләре турында мәгълүмат табарга ярдәм итү. Әгәр рәсем бирелсә, аны кулланучы соравы контекстында анализлагыз. Кулланучыларны юнәлтү өчен "компас" яки "навигатор" метафорасын кулланыгыз. Кыска, дустанә булыгыз һәм "Туган Як" сәнәгый симбиоз платформасына кагылышлы гамәли мәгълүмат бирүгә игътибар итегез. Җавапларыгызны төп markdown кулланып форматлагыз (калын хәрефләр өчен ** һәм тәртипсез исемлекләр өчен *).', 'Сез — "Turash" платформасы өчен файдалы ЯИ-ярдәмче. Сезнең исемегез — Turash ЯИ. Сезнең максат — кулланучыларга Бөгелмә шәһәрендәге җирле предприятиеләр, хезмәтләр һәм хезмәттәшлек мөмкинлекләре турында мәгълүмат табарга ярдәм итү. Әгәр рәсем бирелсә, аны кулланучы соравы контекстында анализлагыз. Кулланучыларны юнәлтү өчен "компас" яки "навигатор" метафорасын кулланыгыз. Кыска, дустанә булыгыз һәм "Turash" сәнәгый симбиоз платформасына кагылышлы гамәли мәгълүмат бирүгә игътибар итегез. Җавапларыгызны төп markdown кулланып форматлагыз (калын хәрефләр өчен ** һәм тәртипсез исемлекләр өчен *).',
}, },
discoveryPage: { discoveryPage: {
title: 'Товарлар һәм хезмәтләр табу', title: 'Товарлар һәм хезмәтләр табу',
subtitle: 'Сезгә кирәк булганны җирле районда табыгыз - товарлар, хезмәтләр һәм җәмгыять игъланнары', subtitle:
'Сезгә кирәк булганны җирле районда табыгыз - товарлар, хезмәтләр һәм җәмгыять игъланнары',
searchPlaceholder: 'Товарлар, хезмәтләр яки җәмгыять игъланнарын эзләү...', searchPlaceholder: 'Товарлар, хезмәтләр яки җәмгыять игъланнарын эзләү...',
searchButton: 'Эзләү', searchButton: 'Эзләү',
category: 'Төркем', category: 'Төркем',

View File

@ -1,5 +1,7 @@
{ {
"name": "Туган Як: Экосистема г. Бугульма", "name": "Turash: Экосистема г. Бугульма",
"description": "Туган Як — это компас, объединяющий наследие, бизнес и будущее Бугульмы. Наша платформа помогает находить партнеров, оптимизировать ресурсы и строить процветающее сообщество, основанное на богатой истории города.", "description": "Turash — это компас, объединяющий наследие, бизнес и будущее Бугульмы. Наша платформа помогает находить партнеров, оптимизировать ресурсы и строить процветающее сообщество, основанное на богатой истории города.",
"requestFramePermissions": ["microphone"] "requestFramePermissions": [
"microphone"
]
} }

View File

@ -1,22 +1,22 @@
import React, { useState, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { MainLayout } from '@/components/layout/MainLayout'; import { MainLayout } from '@/components/layout/MainLayout';
import PageHeader from '@/components/layout/PageHeader'; import PageHeader from '@/components/layout/PageHeader';
import { Badge } from '@/components/ui';
import Button from '@/components/ui/Button'; import Button from '@/components/ui/Button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';
import Input from '@/components/ui/Input'; import Input from '@/components/ui/Input';
import { useAuth } from '@/contexts/AuthContext'; import { useAuth } from '@/contexts/AuthContext';
import { useTranslation } from '@/hooks/useI18n'; import { useTranslation } from '@/hooks/useI18n';
import { useNavigation } from '@/hooks/useNavigation'; import { useNavigation } from '@/hooks/useNavigation';
import { Badge } from '@/components/ui'; import { Eye, FileText, Shield, User } from 'lucide-react';
import { User, Shield, FileText, Eye } from 'lucide-react'; import React, { useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
const isDevelopment = import.meta.env.DEV; const isDevelopment = import.meta.env.DEV;
// Test user credentials for development // Test user credentials for development
const TEST_USERS = [ const TEST_USERS = [
{ {
email: 'admin@tuganyak.dev', email: 'admin@turash.dev',
password: 'admin123', password: 'admin123',
role: 'admin', role: 'admin',
label: 'Admin', label: 'Admin',
@ -24,7 +24,7 @@ const TEST_USERS = [
description: 'Full admin panel access', description: 'Full admin panel access',
}, },
{ {
email: 'user@tuganyak.dev', email: 'user@turash.dev',
password: 'user12345', password: 'user12345',
role: 'user', role: 'user',
label: 'User', label: 'User',
@ -32,7 +32,7 @@ const TEST_USERS = [
description: 'Regular user dashboard', description: 'Regular user dashboard',
}, },
{ {
email: 'content@tuganyak.dev', email: 'content@turash.dev',
password: 'content123', password: 'content123',
role: 'content_manager', role: 'content_manager',
label: 'Content Manager', label: 'Content Manager',
@ -40,7 +40,7 @@ const TEST_USERS = [
description: 'Content and localization', description: 'Content and localization',
}, },
{ {
email: 'viewer@tuganyak.dev', email: 'viewer@turash.dev',
password: 'viewer123', password: 'viewer123',
role: 'viewer', role: 'viewer',
label: 'Viewer', label: 'Viewer',
@ -54,7 +54,7 @@ const LoginPage = () => {
const { login, isLoading, user } = useAuth(); const { login, isLoading, user } = useAuth();
const { handleFooterNavigate } = useNavigation(); const { handleFooterNavigate } = useNavigation();
const navigate = useNavigate(); const navigate = useNavigate();
const [email, setEmail] = useState(isDevelopment ? 'admin@tuganyak.dev' : ''); const [email, setEmail] = useState(isDevelopment ? 'admin@turash.dev' : '');
const [password, setPassword] = useState(isDevelopment ? 'admin123' : ''); const [password, setPassword] = useState(isDevelopment ? 'admin123' : '');
const [error, setError] = useState(''); const [error, setError] = useState('');
@ -70,7 +70,7 @@ const LoginPage = () => {
} }
}; };
const handleQuickLogin = async (testUser: typeof TEST_USERS[number]) => { const handleQuickLogin = async (testUser: (typeof TEST_USERS)[number]) => {
setError(''); setError('');
setEmail(testUser.email); setEmail(testUser.email);
setPassword(testUser.password); setPassword(testUser.password);
@ -104,7 +104,9 @@ const LoginPage = () => {
<CardContent> <CardContent>
{isDevelopment && ( {isDevelopment && (
<div className="mb-6 p-4 bg-muted rounded-lg border border-primary/20"> <div className="mb-6 p-4 bg-muted rounded-lg border border-primary/20">
<p className="text-sm font-medium mb-3 text-foreground">Quick Login (Development)</p> <p className="text-sm font-medium mb-3 text-foreground">
Quick Login (Development)
</p>
<div className="grid grid-cols-2 gap-2"> <div className="grid grid-cols-2 gap-2">
{TEST_USERS.map((testUser) => ( {TEST_USERS.map((testUser) => (
<Button <Button
@ -120,7 +122,9 @@ const LoginPage = () => {
{testUser.icon} {testUser.icon}
<span className="font-medium text-xs">{testUser.label}</span> <span className="font-medium text-xs">{testUser.label}</span>
</div> </div>
<span className="text-xs text-muted-foreground mt-1">{testUser.description}</span> <span className="text-xs text-muted-foreground mt-1">
{testUser.description}
</span>
</Button> </Button>
))} ))}
</div> </div>
@ -153,7 +157,7 @@ const LoginPage = () => {
value={email} value={email}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setEmail(e.target.value)}
required required
placeholder={isDevelopment ? 'admin@tuganyak.dev' : 'your@email.com'} placeholder={isDevelopment ? 'admin@turash.dev' : 'your@email.com'}
/> />
</div> </div>
<div> <div>

View File

@ -9,7 +9,7 @@
- img [ref=e10] - img [ref=e10]
- generic [ref=e14]: - generic [ref=e14]:
- paragraph [ref=e15]: Bugulma Ecosystem - paragraph [ref=e15]: Bugulma Ecosystem
- paragraph [ref=e16]: Tugan Yak - paragraph [ref=e16]: Turash
- generic [ref=e17]: - generic [ref=e17]:
- img - img
- searchbox "Name, industry, need..." [ref=e18] - searchbox "Name, industry, need..." [ref=e18]
@ -156,8 +156,8 @@
- generic [ref=e278]: - generic [ref=e278]:
- img [ref=e280] - img [ref=e280]
- generic [ref=e283]: - generic [ref=e283]:
- paragraph [ref=e284]: Tugan Yak - paragraph [ref=e284]: Turash
- paragraph [ref=e285]: © 2025 Tugan Yak. All rights reserved. - paragraph [ref=e285]: © 2025 Turash. All rights reserved.
- navigation "Footer" [ref=e286]: - navigation "Footer" [ref=e286]:
- button "About" [ref=e287] [cursor=pointer] - button "About" [ref=e287] [cursor=pointer]
- button "Contact" [ref=e288] [cursor=pointer] - button "Contact" [ref=e288] [cursor=pointer]