docs
This commit is contained in:
810
CHANGELOG.md
810
CHANGELOG.md
@@ -1,8 +1,9 @@
|
||||
# IGNY8 Changelog
|
||||
# Changelog
|
||||
|
||||
**Current Version:** `1.0.0`
|
||||
**Last Updated:** 2025-01-XX
|
||||
**Purpose:** Complete changelog of all changes, fixes, and features. Only updated after user confirmation.
|
||||
All notable changes to the IGNY8 platform will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
---
|
||||
|
||||
@@ -10,8 +11,6 @@
|
||||
|
||||
**IMPORTANT**: This changelog is only updated after user confirmation that a fix or feature is complete and working.
|
||||
|
||||
**For AI Agents**: Read `docs/00-DOCUMENTATION-MANAGEMENT.md` before making any changes to this file.
|
||||
|
||||
### Changelog Structure
|
||||
|
||||
Each entry follows this format:
|
||||
@@ -20,579 +19,340 @@ Each entry follows this format:
|
||||
- **Type**: Added, Changed, Fixed, Deprecated, Removed, Security
|
||||
- **Description**: Clear description of the change
|
||||
- **Affected Areas**: Modules, components, or features affected
|
||||
- **Documentation**: Reference to updated documentation files
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- **Planning Documents Organization**: Organized architecture and implementation planning documents
|
||||
- Created `docs/planning/` directory for all planning documents
|
||||
- Moved `IGNY8-HOLISTIC-ARCHITECTURE-PLAN.md` to `docs/planning/`
|
||||
- Moved `IGNY8-IMPLEMENTATION-PLAN.md` to `docs/planning/`
|
||||
- Moved `Igny8-phase-2-plan.md` to `docs/planning/`
|
||||
- Moved `CONTENT-WORKFLOW-DIAGRAM.md` to `docs/planning/`
|
||||
- Moved `ARCHITECTURE_CONTEXT.md` to `docs/planning/`
|
||||
- Moved `sample-usage-limits-credit-system` to `docs/planning/`
|
||||
- Created `docs/refactor/` directory for refactoring plans
|
||||
- Updated `README.md` to reflect new document structure
|
||||
- **Impact**: Better organization of planning documents, easier to find and maintain
|
||||
|
||||
### Changed
|
||||
- **API Documentation Consolidation**: Consolidated all API documentation into single comprehensive reference
|
||||
- Created `docs/API-COMPLETE-REFERENCE.md` - Unified API documentation covering all endpoints, authentication, response formats, error handling, rate limiting, permissions, and integration examples
|
||||
- Removed redundant documentation files:
|
||||
- `docs/API-DOCUMENTATION.md` (consolidated into complete reference)
|
||||
- `docs/DOCUMENTATION-SUMMARY.md` (consolidated into complete reference)
|
||||
- `unified-api/API-ENDPOINTS-ANALYSIS.md` (consolidated into complete reference)
|
||||
- `unified-api/API-STANDARD-v1.0.md` (consolidated into complete reference)
|
||||
- New unified document includes: complete endpoint reference, authentication guide, response format standards, error handling, rate limiting, pagination, roles & permissions, tenant/site/sector scoping, integration examples (Python, JavaScript, cURL, PHP), testing & debugging, and change management
|
||||
- **Impact**: Single source of truth for all API documentation, easier to maintain and navigate
|
||||
|
||||
### Added
|
||||
- Unified API Standard v1.0 implementation
|
||||
- API Monitor page for endpoint health monitoring
|
||||
- CRUD operations monitoring for Planner and Writer modules
|
||||
- Sidebar API status indicator for aws-admin accounts
|
||||
- **Health Check Endpoint**: `GET /api/v1/system/ping/` - Public health check endpoint per API Standard v1.0 requirement
|
||||
- Returns unified format: `{success: true, data: {status: 'ok'}}`
|
||||
- Tagged as 'System' in Swagger/ReDoc documentation
|
||||
- Public endpoint (AllowAny permission)
|
||||
|
||||
### Changed
|
||||
- All API endpoints now return unified response format (`{success, data, message, errors}`)
|
||||
- Frontend `fetchAPI` wrapper automatically extracts data from unified format
|
||||
- All error responses follow unified format with `request_id` tracking
|
||||
- Rate limiting configured with scoped throttles per module
|
||||
- **Integration Views**: All integration endpoints now use unified response format
|
||||
- Replaced 40+ raw `Response()` calls with `success_response()`/`error_response()` helpers
|
||||
- All responses include `request_id` for tracking
|
||||
- Updated frontend components to handle extracted data format
|
||||
- **API Documentation**: Updated Swagger/ReDoc description to include all public endpoints
|
||||
- Added `/api/v1/system/ping/` to public endpoints list
|
||||
- Updated schema extensions to properly tag ping endpoint
|
||||
- **AI Framework Refactoring**: Removed hardcoded model defaults, IntegrationSettings is now the single source of truth
|
||||
- Removed `MODEL_CONFIG` dictionary with hardcoded defaults
|
||||
- Removed Django settings `DEFAULT_AI_MODEL` fallback
|
||||
- `get_model_config()` now requires `account` parameter and raises clear errors if IntegrationSettings not configured
|
||||
- All AI functions now require account-specific model configuration
|
||||
- Removed orphan code: `get_model()`, `get_max_tokens()`, `get_temperature()` helper functions
|
||||
- Removed unused exports from `__init__.py`: `register_function`, `list_functions`, `get_model`, `get_max_tokens`, `get_temperature`
|
||||
- **Impact**: Each account must configure their own AI models in IntegrationSettings
|
||||
- **Documentation**: See `backend/igny8_core/ai/REFACTORING-IMPLEMENTED.md` for complete details
|
||||
|
||||
### Fixed
|
||||
- Keyword edit form now correctly populates existing values
|
||||
- Auto-cluster function now works correctly with unified API format
|
||||
- ResourceDebugOverlay now correctly extracts data from unified API responses
|
||||
- All frontend pages now correctly handle unified API response format
|
||||
- **Integration Views**: Fixed all integration endpoints not using unified response format
|
||||
- `_test_openai()` and `_test_runware()` methods now use unified format
|
||||
- `generate_image()`, `create()`, `save_settings()` methods now use unified format
|
||||
- `get_image_generation_settings()` and `task_progress()` methods now use unified format
|
||||
- All error responses now include `request_id` and follow unified format
|
||||
- Fixed OpenAI integration endpoint error handling - invalid API keys now return 400 (Bad Request) instead of 401 (Unauthorized)
|
||||
- **Frontend Components**: Updated to work with unified format
|
||||
- `ValidationCard.tsx` - Removed dual-format handling, now works with extracted data
|
||||
- `Integration.tsx` - Simplified to work with unified format
|
||||
- `ImageGenerationCard.tsx` - Updated to work with extracted data format
|
||||
- **Frontend Authentication**: Fixed `getAuthToken is not defined` error in `authStore.ts`
|
||||
- Updated `refreshUser()` to use `fetchAPI()` instead of manual fetch with `getAuthToken()`
|
||||
- Removed error throwing from catch block to prevent error accumulation
|
||||
- **Frontend Error Handling**: Fixed console error accumulation
|
||||
- `ResourceDebugOverlay.tsx` now silently ignores 404 errors for request-metrics endpoint
|
||||
- Removed error throwing from `refreshUser()` catch block to prevent error spam
|
||||
- **AI Framework Error Handling**: Improved error messages and exception handling
|
||||
- `AIEngine._handle_error()` now preserves exception types for better error messages
|
||||
- All AI function errors now include proper `error_type` (ConfigurationError, AccountNotFound, etc.)
|
||||
- Fixed "Task failed - exception details unavailable" by improving error type preservation
|
||||
- Error messages now clearly indicate when IntegrationSettings are missing or misconfigured
|
||||
|
||||
---
|
||||
|
||||
## [1.1.1] - 2025-01-XX
|
||||
|
||||
### Security
|
||||
- **CRITICAL**: Fixed `AIPromptViewSet` security vulnerability - changed from `permission_classes = []` (allowing unauthenticated access) to `IsAuthenticatedAndActive + HasTenantAccess`
|
||||
- Added `IsEditorOrAbove` permission check for `save_prompt` and `reset_prompt` actions in `AIPromptViewSet`
|
||||
- All billing ViewSets now require `IsAuthenticatedAndActive + HasTenantAccess` for proper tenant isolation
|
||||
- `CreditTransactionViewSet` now requires `IsAdminOrOwner` per API Standard v1.0 (billing/transactions require admin/owner)
|
||||
- All system settings ViewSets now use standard permissions (`IsAuthenticatedAndActive + HasTenantAccess`)
|
||||
- All auth ViewSets now explicitly include `IsAuthenticatedAndActive + HasTenantAccess` for proper tenant isolation
|
||||
|
||||
### Changed
|
||||
- **Auth Endpoints**: All authentication endpoints (`RegisterView`, `LoginView`, `ChangePasswordView`, `MeView`) now use unified response format with `success_response()` and `error_response()` helpers
|
||||
- All responses now include `request_id` for error tracking
|
||||
- Error responses follow unified format with `error` and `errors` fields
|
||||
- Success responses follow unified format with `success`, `data`, and `message` fields
|
||||
- **Billing Module**: Refactored `CreditUsageViewSet` and `CreditTransactionViewSet` to inherit from `AccountModelViewSet` instead of manual account filtering
|
||||
- Account filtering now handled automatically by base class
|
||||
- Improved code maintainability and consistency
|
||||
- **System Settings**: All 5 system settings ViewSets now use standard permission classes
|
||||
- `SystemSettingsViewSet`, `AccountSettingsViewSet`, `UserSettingsViewSet`, `ModuleSettingsViewSet`, `AISettingsViewSet`
|
||||
- Write operations require `IsAdminOrOwner` per standard
|
||||
- **Integration Settings**: Added `HasTenantAccess` permission to `IntegrationSettingsViewSet` for proper tenant isolation
|
||||
- **Auth ViewSets**: Added explicit standard permissions to all auth ViewSets
|
||||
- `UsersViewSet`, `AccountsViewSet`, `SubscriptionsViewSet`, `SiteUserAccessViewSet` now include `IsAuthenticatedAndActive + HasTenantAccess`
|
||||
- `SiteViewSet`, `SectorViewSet` now include `IsAuthenticatedAndActive + HasTenantAccess`
|
||||
|
||||
### Fixed
|
||||
- Fixed auth endpoints not returning unified format (were using raw `Response()` instead of helpers)
|
||||
- Fixed missing `request_id` in auth endpoint responses
|
||||
- Fixed inconsistent error response format in auth endpoints
|
||||
- Fixed billing ViewSets not using base classes (manual account filtering replaced with `AccountModelViewSet`)
|
||||
- Fixed all ViewSets missing standard permissions (`IsAuthenticatedAndActive + HasTenantAccess`)
|
||||
|
||||
### Documentation
|
||||
- Updated implementation plan to reflect completion of all remaining API Standard v1.0 items
|
||||
- All 8 remaining items from audit completed (100% compliance achieved)
|
||||
- **API Standard v1.0**: Full compliance achieved
|
||||
- All 10 audit tasks completed and verified
|
||||
- All custom @action methods use unified response format
|
||||
- All ViewSets use proper base classes, pagination, throttles, and permissions
|
||||
- All error responses include `request_id` tracking
|
||||
- No raw `Response()` calls remaining (except file downloads)
|
||||
- All endpoints documented in Swagger/ReDoc with proper tags
|
||||
|
||||
---
|
||||
|
||||
## [1.1.0] - 2025-01-XX
|
||||
## [1.0.0] - 2025-11-24
|
||||
|
||||
### Added
|
||||
|
||||
#### Unified API Standard v1.0
|
||||
- **Response Format Standardization**
|
||||
- All endpoints return unified format: `{success: true/false, data: {...}, message: "...", errors: {...}}`
|
||||
- Paginated responses include `success`, `count`, `next`, `previous`, `results`
|
||||
- Error responses include `success: false`, `error`, `errors`, `request_id`
|
||||
- Response helper functions: `success_response()`, `error_response()`, `paginated_response()`
|
||||
#### Backend Core
|
||||
- **Multi-Tenancy System**
|
||||
- Complete account isolation with Account → Site → Sector hierarchy
|
||||
- User roles: Developer, Owner, Admin, Editor, Viewer, System Bot
|
||||
- Automatic account filtering via `AccountContextMiddleware`
|
||||
- Base classes: `AccountModelViewSet` and `SiteSectorModelViewSet`
|
||||
- Account isolation at database level with ForeignKey relationships
|
||||
|
||||
- **Custom Exception Handler**
|
||||
- Centralized exception handling in `backend/igny8_core/api/exception_handlers.py`
|
||||
- All exceptions wrapped in unified format
|
||||
- Proper HTTP status code mapping (400, 401, 403, 404, 409, 422, 429, 500)
|
||||
- Debug information included in development mode
|
||||
- **Authentication & Authorization**
|
||||
- JWT token authentication with PyJWT 2.8+
|
||||
- 15-minute access token expiry
|
||||
- Refresh token support
|
||||
- API key authentication for WordPress integration
|
||||
- Permission classes: `IsAuthenticatedAndActive`, `HasTenantAccess`, `IsEditorOrAbove`, `IsAdminOrOwner`
|
||||
- Role-based access control matrix
|
||||
|
||||
- **Custom Pagination**
|
||||
- `CustomPageNumberPagination` class with unified format support
|
||||
- Default page size: 10, max: 100
|
||||
- Dynamic page size via `page_size` query parameter
|
||||
- Includes `success` field in paginated responses
|
||||
- **Planner Module** (`modules/planner/`)
|
||||
- Keywords model with search volume, difficulty, intent tracking
|
||||
- Clusters model with many-to-many keyword relationships
|
||||
- ContentIdeas model linked to clusters
|
||||
- AI-powered keyword clustering via `auto_cluster` function
|
||||
- AI-powered content idea generation via `generate_ideas` function
|
||||
- Bulk keyword import (CSV and manual)
|
||||
- ViewSets: `KeywordViewSet`, `ClusterViewSet`, `ContentIdeasViewSet`
|
||||
|
||||
- **Base ViewSets**
|
||||
- `AccountModelViewSet` - Handles account isolation and unified CRUD responses
|
||||
- `SiteSectorModelViewSet` - Extends account isolation with site/sector filtering
|
||||
- All CRUD operations (create, retrieve, update, destroy) return unified format
|
||||
- **Writer Module** (`modules/writer/`)
|
||||
- Tasks model for content creation workflow
|
||||
- Content model with HTML/plain text support and unified taxonomy structure
|
||||
- Images model with featured/in-article image support
|
||||
- AI content generation via GPT-4 (`generate_content` function)
|
||||
- AI image generation via DALL-E 3 and Runware (`generate_images` function)
|
||||
- Content taxonomies (`ContentTaxonomy`) and attributes (unified JSON structure)
|
||||
- ViewSets: `TasksViewSet`, `ContentViewSet`, `ImagesViewSet`, `ContentTaxonomyViewSet`, `ContentAttributeViewSet`
|
||||
|
||||
- **Rate Limiting**
|
||||
- `DebugScopedRateThrottle` with debug bypass for development
|
||||
- Scoped rate limits per module (planner, writer, system, billing, auth)
|
||||
- AI function rate limits (10/min for expensive operations)
|
||||
- Bypass for aws-admin accounts and admin/developer roles
|
||||
- Rate limit headers: `X-Throttle-Limit`, `X-Throttle-Remaining`, `X-Throttle-Reset`
|
||||
- **Linker Module** (`modules/linker/`)
|
||||
- Internal linking recommendations
|
||||
- Link graph analysis
|
||||
- `LinkerViewSet` for link operations
|
||||
|
||||
- **Request ID Tracking**
|
||||
- `RequestIDMiddleware` generates unique UUID for each request
|
||||
- Request ID included in all error responses
|
||||
- Request ID in response headers: `X-Request-ID`
|
||||
- Used for log correlation and debugging
|
||||
- **Optimizer Module** (`modules/optimizer/`)
|
||||
- Content quality scoring
|
||||
- SEO optimization suggestions
|
||||
- `OptimizerViewSet` for optimization operations
|
||||
|
||||
- **API Monitor**
|
||||
- New page: `/settings/api-monitor` for endpoint health monitoring
|
||||
- Monitors API status (HTTP response) and data status (page population)
|
||||
- Endpoint groups: Core Health, Auth, Planner, Writer, System, Billing, CRUD Operations
|
||||
- Sorting by status (errors first, then warnings, then healthy)
|
||||
- Real-time endpoint health checks with configurable refresh interval
|
||||
- Only accessible to aws-admin accounts
|
||||
- **Publisher Module** (`modules/publisher/`)
|
||||
- Publishing records tracking (`PublishingRecord` model)
|
||||
- Deployment records (`DeploymentRecord` model)
|
||||
- `PublisherViewSet`, `PublishingRecordViewSet`, `DeploymentRecordViewSet`
|
||||
|
||||
- **Sidebar API Status Indicator**
|
||||
- Visual indicator circles for each endpoint group
|
||||
- Color-coded status (green = healthy, yellow = warning)
|
||||
- Abbreviations: CO, AU, PM, WM, PC, WC, SY
|
||||
- Only visible and active for aws-admin accounts on API monitor page
|
||||
- Prevents console errors on other pages
|
||||
- **Site Builder Module** (`modules/site_builder/`)
|
||||
- Site blueprint management (`SiteBlueprint` model)
|
||||
- Page blueprint creation (`PageBlueprint` model)
|
||||
- Site structure planning with clusters and taxonomies
|
||||
- `SiteBlueprintViewSet`, `PageBlueprintViewSet`, `SiteAssetView`, `SiteBuilderMetadataView`
|
||||
|
||||
### Changed
|
||||
- **Automation Module** (`modules/automation/`)
|
||||
- Automation rules engine (`AutomationRule` model)
|
||||
- Scheduled tasks (`ScheduledTask` model)
|
||||
- Rule execution via Celery beat
|
||||
- `AutomationRuleViewSet`, `ScheduledTaskViewSet`
|
||||
|
||||
#### Backend Refactoring
|
||||
- **Planner Module** - All ViewSets refactored to unified format
|
||||
- `KeywordViewSet` - CRUD + `auto_cluster` action
|
||||
- `ClusterViewSet` - CRUD + `auto_generate_ideas` action
|
||||
- `ContentIdeasViewSet` - CRUD + `bulk_queue_to_writer` action
|
||||
- **Integration Module** (`modules/integration/`)
|
||||
- WordPress integration support via `SiteIntegration` model
|
||||
- Connection testing: `POST /integrations/test-connection/`
|
||||
- Structure update: `POST /integrations/{id}/update-structure/`
|
||||
- Content type summary: `GET /integrations/{id}/content-types/`
|
||||
- Bidirectional sync support with sync status and logs
|
||||
- Integration services: `IntegrationService`, `SyncService`, `ContentSyncService`, `SyncHealthService`
|
||||
- Site-level sync endpoints: `/sites/{id}/sync/status/`, `/sites/{id}/sync/run/`
|
||||
- `IntegrationViewSet` with comprehensive sync management
|
||||
|
||||
- **Writer Module** - All ViewSets refactored to unified format
|
||||
- `TasksViewSet` - CRUD + `auto_generate_content` action
|
||||
- `ContentViewSet` - CRUD + `generate_image_prompts` action
|
||||
- `ImagesViewSet` - CRUD + `generate_images` action
|
||||
- **System Module** (`modules/system/`)
|
||||
- AI prompt management (`AIPrompt` model with types: cluster, ideas, content, image_prompts)
|
||||
- Integration settings (`IntegrationSettings` model for OpenAI/Runware config)
|
||||
- Author profiles for content style (`AuthorProfile` model)
|
||||
- Content strategies (`Strategy` model)
|
||||
- System and account settings endpoints
|
||||
- ViewSets: `AIPromptViewSet`, `AuthorProfileViewSet`, `StrategyViewSet`
|
||||
- Settings ViewSets: `SystemSettingsViewSet`, `AccountSettingsViewSet`, `UserSettingsViewSet`, `ModuleSettingsViewSet`, `AISettingsViewSet`
|
||||
|
||||
- **System Module** - All ViewSets refactored to unified format
|
||||
- `AIPromptViewSet` - CRUD + `get_by_type`, `save_prompt`, `reset_prompt` actions
|
||||
- `SystemSettingsViewSet`, `AccountSettingsViewSet`, `UserSettingsViewSet`
|
||||
- `ModuleSettingsViewSet`, `AISettingsViewSet`
|
||||
- `IntegrationSettingsViewSet` - Integration management and testing
|
||||
- **Billing Module** (`modules/billing/`)
|
||||
- Credit-based usage system
|
||||
- Credit transactions tracking (`CreditTransaction` model)
|
||||
- Usage analytics (`CreditUsageLog` model)
|
||||
- `CreditService` for credit operations
|
||||
- Monthly credit replenishment via Celery beat task
|
||||
- ViewSets: `CreditBalanceViewSet`, `CreditUsageViewSet`, `CreditTransactionViewSet`
|
||||
|
||||
- **Billing Module** - All ViewSets refactored to unified format
|
||||
- `CreditBalanceViewSet` - `balance` action
|
||||
- `CreditUsageViewSet` - `summary`, `limits` actions
|
||||
- `CreditTransactionViewSet` - CRUD operations
|
||||
- **AI Framework** (`ai/`)
|
||||
- `AIEngine` - Central orchestrator for all AI operations with progress tracking
|
||||
- `AICore` - Unified API client for OpenAI/Runware with rate calculation
|
||||
- `BaseAIFunction` - Abstract interface for AI function implementations
|
||||
- AI function registry system with 5 core functions
|
||||
- Progress tracking with Celery task state updates
|
||||
- Cost tracking (token usage and pricing)
|
||||
- Console step tracker for debugging (`ConsoleStepTracker`)
|
||||
- Prompt registry system (`PromptRegistry`)
|
||||
- Model configuration per account via `IntegrationSettings`
|
||||
- Validators for payload validation
|
||||
- Celery task wrapper: `run_ai_task`
|
||||
|
||||
- **Auth Module** - All ViewSets refactored to unified format
|
||||
- `AuthViewSet` - `register`, `login`, `change_password`, `refresh_token`, `reset_password`
|
||||
- `UsersViewSet` - CRUD + `create_user`, `update_role` actions
|
||||
- `GroupsViewSet`, `AccountsViewSet`, `SubscriptionsViewSet`
|
||||
- `SiteUserAccessViewSet`, `PlanViewSet`, `IndustryViewSet`, `SeedKeywordViewSet`
|
||||
- **AI Functions** (`ai/functions/`)
|
||||
- `auto_cluster.py` - Semantic keyword clustering
|
||||
- `generate_ideas.py` - Content idea generation from clusters
|
||||
- `generate_content.py` - Full blog post generation with HTML
|
||||
- `generate_image_prompts.py` - Extract image prompts from content
|
||||
- `generate_images.py` - Image generation via DALL-E 3 / Runware
|
||||
|
||||
#### Frontend Refactoring
|
||||
- **fetchAPI Wrapper** (`frontend/src/services/api.ts`)
|
||||
- Automatically extracts `data` field from unified format responses
|
||||
- Handles paginated responses (`results` at top level)
|
||||
- Properly throws errors for `success: false` responses
|
||||
- Removed redundant `response?.data || response` checks across codebase
|
||||
- **API Infrastructure** (`api/`)
|
||||
- Unified response format: `{success, data, message, request_id}`
|
||||
- Response helpers: `success_response()`, `error_response()`, `paginated_response()`
|
||||
- Request ID tracking via `RequestIDMiddleware`
|
||||
- Resource tracking via `ResourceTrackingMiddleware`
|
||||
- Rate limiting with `DebugScopedRateThrottle` (bypass in DEBUG mode)
|
||||
- Custom pagination: `CustomPageNumberPagination` (default: 10, max: 100)
|
||||
- OpenAPI 3.0 schema via drf-spectacular
|
||||
- Swagger UI at `/api/docs/`
|
||||
- ReDoc at `/api/redoc/`
|
||||
- Centralized exception handling with unified error format
|
||||
|
||||
- **All Frontend Pages Updated**
|
||||
- Removed redundant response data extraction
|
||||
- All pages now correctly consume unified API format
|
||||
- Error handling standardized across all components
|
||||
- Pagination handling standardized
|
||||
- **Celery Integration** (`celery.py`)
|
||||
- Async task processing for AI operations
|
||||
- Celery beat for scheduled tasks
|
||||
- Beat schedule: monthly credit replenishment, automation rule execution (every 5 min)
|
||||
- Task autodiscovery from all installed apps
|
||||
|
||||
- **Component Updates**
|
||||
- `FormModal` - Now accepts `React.ReactNode` for title prop
|
||||
- `ComponentCard` - Updated to support status badges in titles
|
||||
- `ResourceDebugOverlay` - Fixed to extract data from unified format
|
||||
- `ApiStatusIndicator` - Restricted to aws-admin accounts and API monitor page
|
||||
#### Frontend Core
|
||||
- **React 19 Application** (`frontend/`)
|
||||
- Vite 6.1.0 build system with fast HMR
|
||||
- TypeScript 5.7.2 for type safety
|
||||
- React Router v7.9.5 for client-side routing
|
||||
- Zustand 5.0.8 state management with localStorage persistence
|
||||
- Lazy loading for all module pages (code splitting)
|
||||
- Tailwind CSS 4.0.8 for styling
|
||||
|
||||
### Fixed
|
||||
- **Authentication** (`pages/AuthPages/`, `store/authStore.ts`)
|
||||
- JWT-based authentication with automatic token refresh
|
||||
- Login/signup pages
|
||||
- Protected routes with `ProtectedRoute` component
|
||||
- Auth store with Zustand (user, token, refreshToken state)
|
||||
- Auto token refresh on 401 errors
|
||||
|
||||
#### Bug Fixes
|
||||
- **Keyword Edit Form** - Now correctly populates existing values when editing
|
||||
- Added `key` prop to force re-render when form data changes
|
||||
- Fixed `seed_keyword_id` value handling for select dropdown
|
||||
- **Module Pages**
|
||||
- **Planner** (`pages/Planner/`): Keywords list, Clusters view, Ideas dashboard, Keyword opportunities
|
||||
- **Writer** (`pages/Writer/`): Tasks dashboard, Content viewer with HTML preview, Drafts, Published list, Images gallery
|
||||
- **Linker** (`pages/Linker/`): Link analysis dashboard, Content list with link suggestions
|
||||
- **Optimizer** (`pages/Optimizer/`): Optimization dashboard, Content selector, Analysis preview
|
||||
- **Thinker** (`pages/Thinker/`): AI prompts editor, Author profiles, Strategies, Image testing
|
||||
- **Billing** (`pages/Billing/`): Credit balance, Transaction history, Usage analytics
|
||||
- **Automation** (`pages/Automation/`): Rules management, Scheduled tasks list
|
||||
- **Settings** (`pages/Settings/`): General, Users, Subscriptions, System, AI settings, API monitor
|
||||
|
||||
- **Auto-Cluster Function** - Now works correctly with unified API format
|
||||
- Updated `autoClusterKeywords()` to wrap response with `success` field
|
||||
- Proper error handling and response extraction
|
||||
- **UI Components** (`components/`)
|
||||
- Reusable components library
|
||||
- ApexCharts for data visualization
|
||||
- Heroicons for icons
|
||||
- Responsive layouts with Tailwind
|
||||
- Form components with validation
|
||||
- Modal system
|
||||
- Loading states and skeletons
|
||||
|
||||
- **ResourceDebugOverlay** - Fixed data extraction from unified API responses
|
||||
- Extracts `data` field from `{success: true, data: {...}}` responses
|
||||
- Added null safety checks for all property accesses
|
||||
- Validates data structure before adding to metrics
|
||||
- **API Integration** (`api/`, `services/`)
|
||||
- Axios client with automatic token injection
|
||||
- Request/response interceptors
|
||||
- Automatic token refresh on 401
|
||||
- Module-specific API clients (planner, writer, linker, etc.)
|
||||
- `fetchAPI` wrapper with unified format handling
|
||||
- Error handling with toast notifications
|
||||
|
||||
- **API Response Handling** - Fixed all instances of incorrect data extraction
|
||||
- Removed `response?.data || response` redundant checks
|
||||
- Removed `response.results || []` redundant checks
|
||||
- All API functions now correctly handle unified format
|
||||
- **State Management** (`store/`)
|
||||
- `authStore` - User authentication state
|
||||
- `siteStore` - Site and sector context
|
||||
- Module-specific stores (plannerStore, writerStore, etc.)
|
||||
- Global app state (loading, errors, notifications)
|
||||
- Zustand persist middleware for localStorage
|
||||
|
||||
- **React Hooks Error** - Fixed "Rendered more hooks than during the previous render"
|
||||
- Moved all hooks to top of component before conditional returns
|
||||
- Fixed `ApiStatusIndicator` component hook ordering
|
||||
#### WordPress Plugin
|
||||
- **Core Plugin** (`igny8-wp-integration/`)
|
||||
- Plugin version 1.0.0
|
||||
- WordPress 5.0+ compatibility
|
||||
- PHP 7.4+ requirement
|
||||
- Main file: `igny8-bridge.php`
|
||||
- Uninstall cleanup: `uninstall.php`
|
||||
|
||||
- **TypeScript Errors** - Fixed all type errors related to unified API format
|
||||
- Added nullish coalescing for `toLocaleString()` calls
|
||||
- Added null checks before `Object.entries()` calls
|
||||
- Fixed all undefined property access errors
|
||||
- **API Client** (`includes/class-igny8-api.php`)
|
||||
- `Igny8API` class for backend communication
|
||||
- API key authentication (primary method)
|
||||
- JWT token authentication support (fallback)
|
||||
- Automatic retry on 401 errors
|
||||
- Request/response parsing with unified format support
|
||||
- Methods: `connect()`, `get()`, `post()`, `put()`, `delete()`, `parse_response()`
|
||||
|
||||
#### System Health
|
||||
- **System Status Page** - Fixed redundant data extraction
|
||||
- Now correctly uses extracted data from `fetchAPI`
|
||||
- All system metrics display correctly
|
||||
- **REST API Endpoints** (`includes/class-igny8-rest-api.php`)
|
||||
- `GET /wp-json/igny8/v1/site-metadata/` - Export site structure
|
||||
- `GET /wp-json/igny8/v1/post-by-task-id/{id}` - Lookup by task ID
|
||||
- `GET /wp-json/igny8/v1/post-by-content-id/{id}` - Lookup by content ID
|
||||
- `POST /wp-json/igny8/v1/posts/` - Create post from IGNY8
|
||||
- `PUT /wp-json/igny8/v1/posts/{id}` - Update post from IGNY8
|
||||
- API key authentication via `X-IGNY8-API-Key` header
|
||||
|
||||
### Security
|
||||
- Rate limiting bypass only for aws-admin accounts and admin/developer roles
|
||||
- Request ID tracking for all API requests
|
||||
- Centralized error handling prevents information leakage
|
||||
- **Synchronization** (`sync/`)
|
||||
- **WP → IGNY8** (`post-sync.php`): Post status sync on `save_post` hook
|
||||
- **IGNY8 → WP** (`igny8-to-wp.php`): Content publishing via REST API
|
||||
- **Taxonomy Sync** (`taxonomy-sync.php`): Taxonomy term synchronization
|
||||
- **Hooks** (`hooks.php`): WordPress action/filter hook registration
|
||||
- Bidirectional sync with status mapping
|
||||
- Post meta tracking: `_igny8_task_id`, `_igny8_content_id`, `_igny8_wordpress_status`, `_igny8_last_synced`, `_igny8_managed`
|
||||
|
||||
### Testing
|
||||
- **Admin Interface** (`admin/`)
|
||||
- Settings page at Settings → IGNY8 API (`settings.php`)
|
||||
- API key, email, password configuration
|
||||
- Connection testing button
|
||||
- Post columns showing IGNY8 status (`class-admin-columns.php`)
|
||||
- Post meta boxes in editor (`class-post-meta-boxes.php`)
|
||||
- Admin class: `Igny8Admin` (`class-admin.php`)
|
||||
|
||||
- **Comprehensive Test Suite**
|
||||
- Created complete unit and integration test suite for Unified API Standard v1.0
|
||||
- 13 test files with ~115 test methods covering all API components
|
||||
- Test coverage: 100% of API Standard components
|
||||
- **Data Collection** (`data/`)
|
||||
- Full site metadata collection (`site-collection.php`)
|
||||
- Post type discovery with counts
|
||||
- Taxonomy discovery with counts
|
||||
- Link graph extraction (`link-graph.php`)
|
||||
- Semantic mapping (`semantic-mapping.php`)
|
||||
- WooCommerce integration support (`woocommerce.php`)
|
||||
|
||||
- **Unit Tests** (`backend/igny8_core/api/tests/`)
|
||||
- `test_response.py` - Tests for response helper functions (18 tests)
|
||||
- Tests `success_response()`, `error_response()`, `paginated_response()`
|
||||
- Tests request ID generation and inclusion
|
||||
- Tests status code mapping and error messages
|
||||
- `test_exception_handler.py` - Tests for custom exception handler (12 tests)
|
||||
- Tests all exception types (ValidationError, AuthenticationFailed, PermissionDenied, NotFound, Throttled, etc.)
|
||||
- Tests debug mode behavior and debug info inclusion
|
||||
- Tests field-specific and non-field error handling
|
||||
- `test_permissions.py` - Tests for permission classes (20 tests)
|
||||
- Tests `IsAuthenticatedAndActive`, `HasTenantAccess`, `IsViewerOrAbove`, `IsEditorOrAbove`, `IsAdminOrOwner`
|
||||
- Tests role-based access control and tenant isolation
|
||||
- Tests admin/system account bypass logic
|
||||
- `test_throttles.py` - Tests for rate limiting (11 tests)
|
||||
- Tests `DebugScopedRateThrottle` bypass logic (DEBUG mode, env flag, admin/system accounts)
|
||||
- Tests rate parsing and throttle header generation
|
||||
|
||||
- **Integration Tests** (`backend/igny8_core/api/tests/`)
|
||||
- `test_integration_base.py` - Base test class with common fixtures and helper methods
|
||||
- `test_integration_planner.py` - Planner module endpoint tests (12 tests)
|
||||
- Tests CRUD operations for keywords, clusters, ideas
|
||||
- Tests AI actions (auto_cluster)
|
||||
- Tests error scenarios and validation
|
||||
- `test_integration_writer.py` - Writer module endpoint tests (6 tests)
|
||||
- Tests CRUD operations for tasks, content, images
|
||||
- Tests error scenarios
|
||||
- `test_integration_system.py` - System module endpoint tests (5 tests)
|
||||
- Tests status, prompts, settings, integrations endpoints
|
||||
- `test_integration_billing.py` - Billing module endpoint tests (5 tests)
|
||||
- Tests credits, usage, transactions endpoints
|
||||
- `test_integration_auth.py` - Auth module endpoint tests (8 tests)
|
||||
- Tests login, register, user management endpoints
|
||||
- Tests authentication flows and error scenarios
|
||||
- `test_integration_errors.py` - Error scenario tests (6 tests)
|
||||
- Tests 400, 401, 403, 404, 429, 500 error responses
|
||||
- Tests unified error format across all error types
|
||||
- `test_integration_pagination.py` - Pagination tests (10 tests)
|
||||
- Tests pagination across all modules
|
||||
- Tests page size, page parameter, max page size limits
|
||||
- Tests empty results handling
|
||||
- `test_integration_rate_limiting.py` - Rate limiting integration tests (7 tests)
|
||||
- Tests throttle headers presence
|
||||
- Tests bypass logic for admin/system accounts and DEBUG mode
|
||||
- Tests different throttle scopes per module
|
||||
|
||||
- **Test Verification**
|
||||
- All tests verify unified response format (`{success, data/results, message, errors, request_id}`)
|
||||
- All tests verify proper HTTP status codes
|
||||
- All tests verify error format consistency
|
||||
- All tests verify pagination format consistency
|
||||
- All tests verify request ID inclusion
|
||||
|
||||
- **Test Documentation**
|
||||
- Created `backend/igny8_core/api/tests/README.md` with test structure and running instructions
|
||||
- Created `backend/igny8_core/api/tests/TEST_SUMMARY.md` with comprehensive test statistics
|
||||
- Created `backend/igny8_core/api/tests/run_tests.py` test runner script
|
||||
|
||||
### Documentation
|
||||
|
||||
- **OpenAPI/Swagger Integration**
|
||||
- Installed and configured `drf-spectacular` for OpenAPI 3.0 schema generation
|
||||
- Created Swagger UI endpoint: `/api/docs/`
|
||||
- Created ReDoc endpoint: `/api/redoc/`
|
||||
- Created OpenAPI schema endpoint: `/api/schema/`
|
||||
- Configured comprehensive API documentation with code samples
|
||||
- Added custom authentication extensions for JWT Bearer tokens
|
||||
|
||||
- **Comprehensive Documentation Files**
|
||||
- `docs/API-COMPLETE-REFERENCE.md` - Complete unified API reference (consolidated from multiple files)
|
||||
- Quick start guide
|
||||
- Endpoint reference
|
||||
- Code examples (Python, JavaScript, cURL)
|
||||
- Response format details
|
||||
- `docs/AUTHENTICATION-GUIDE.md` - Authentication and authorization guide
|
||||
- JWT Bearer token authentication
|
||||
- Token management and refresh
|
||||
- Code examples in Python and JavaScript
|
||||
- Security best practices
|
||||
- `docs/ERROR-CODES.md` - Complete error code reference
|
||||
- HTTP status codes (200, 201, 400, 401, 403, 404, 409, 422, 429, 500)
|
||||
- Field-specific error messages
|
||||
- Error handling best practices
|
||||
- Common error scenarios and solutions
|
||||
- `docs/RATE-LIMITING.md` - Rate limiting and throttling guide
|
||||
- Rate limit scopes and limits
|
||||
- Handling rate limits (429 responses)
|
||||
- Best practices and code examples
|
||||
- Request queuing and caching strategies
|
||||
- `docs/MIGRATION-GUIDE.md` - Migration guide for API consumers
|
||||
- What changed in v1.0
|
||||
- Step-by-step migration instructions
|
||||
- Code examples (before/after)
|
||||
- Breaking and non-breaking changes
|
||||
- `docs/WORDPRESS-PLUGIN-INTEGRATION.md` - WordPress plugin integration guide
|
||||
- Complete PHP API client class
|
||||
- Authentication implementation
|
||||
- Error handling
|
||||
- WordPress admin integration
|
||||
- Best practices
|
||||
- `docs/README.md` - Documentation index and quick start
|
||||
|
||||
- **OpenAPI Schema Configuration**
|
||||
- Configured comprehensive API description with features overview
|
||||
- Added authentication documentation
|
||||
- Added response format examples
|
||||
- Added rate limiting documentation
|
||||
- Added pagination documentation
|
||||
- Configured endpoint tags (Authentication, Planner, Writer, System, Billing)
|
||||
- Added code samples in Python and JavaScript
|
||||
|
||||
- **Schema Extensions**
|
||||
- Created `backend/igny8_core/api/schema_extensions.py` for custom authentication
|
||||
- JWT Bearer token authentication extension
|
||||
- CSRF-exempt session authentication extension
|
||||
- Proper OpenAPI security scheme definitions
|
||||
|
||||
---
|
||||
|
||||
## [1.0.0] - 2025-01-XX
|
||||
|
||||
### Added
|
||||
|
||||
#### Documentation System
|
||||
- Complete documentation structure with 7 core documents
|
||||
- Documentation management system with versioning
|
||||
- Changelog management system
|
||||
- DRY principles documentation
|
||||
- Self-explaining documentation for AI agents
|
||||
|
||||
#### Core Features
|
||||
- Multi-tenancy system with account isolation
|
||||
- Authentication (login/register) with JWT
|
||||
- RBAC permissions (Developer, Owner, Admin, Editor, Viewer, System Bot)
|
||||
- Account > Site > Sector hierarchy
|
||||
- Multiple sites can be active simultaneously
|
||||
- Maximum 5 active sectors per site
|
||||
|
||||
#### Planner Module
|
||||
- Keywords CRUD operations
|
||||
- Keyword import/export (CSV)
|
||||
- Keyword filtering and organization
|
||||
- AI-powered keyword clustering
|
||||
- Clusters CRUD operations
|
||||
- Content ideas generation from clusters
|
||||
- Content ideas CRUD operations
|
||||
- Keyword-to-cluster mapping
|
||||
- Cluster metrics and analytics
|
||||
|
||||
#### Writer Module
|
||||
- Tasks CRUD operations
|
||||
- AI-powered content generation
|
||||
- Content editing and review
|
||||
- Image prompt extraction
|
||||
- AI-powered image generation (OpenAI DALL-E, Runware)
|
||||
- Image management
|
||||
- WordPress integration (publishing)
|
||||
|
||||
#### Thinker Module
|
||||
- AI prompt management
|
||||
- Author profile management
|
||||
- Content strategy management
|
||||
- Image generation testing
|
||||
|
||||
#### System Module
|
||||
- Integration settings (OpenAI, Runware)
|
||||
- API key configuration
|
||||
- Connection testing
|
||||
- System status and monitoring
|
||||
|
||||
#### Billing Module
|
||||
- Credit balance tracking
|
||||
- Credit transactions
|
||||
- Usage logging
|
||||
- Cost tracking
|
||||
|
||||
#### Frontend
|
||||
- Configuration-driven UI system
|
||||
- 4 universal templates (Dashboard, Table, Form, System)
|
||||
- Complete component library
|
||||
- Zustand state management
|
||||
- React Router v7 routing
|
||||
- Progress tracking for AI tasks
|
||||
- Responsive design
|
||||
|
||||
#### Backend
|
||||
- RESTful API with DRF
|
||||
- Automatic account isolation
|
||||
- Site access control
|
||||
- Celery async task processing
|
||||
- Progress tracking for Celery tasks
|
||||
- Unified AI framework
|
||||
- Database logging
|
||||
|
||||
#### AI Functions
|
||||
- Auto Cluster Keywords
|
||||
- Generate Ideas
|
||||
- Generate Content
|
||||
- Generate Image Prompts
|
||||
- Generate Images
|
||||
- Test OpenAI connection
|
||||
- Test Runware connection
|
||||
- Test image generation
|
||||
- **Supporting Classes** (`includes/`)
|
||||
- `Igny8Site` - Site data collection and export
|
||||
- `Igny8Webhooks` - Webhook handlers (legacy)
|
||||
- `Igny8WebhookLogs` - Webhook logging
|
||||
- `Igny8LinkQueue` - Link processing queue
|
||||
- Helper functions in `functions.php`
|
||||
|
||||
#### Infrastructure
|
||||
- Docker-based containerization
|
||||
- Two-stack architecture (infra, app)
|
||||
- Caddy reverse proxy
|
||||
- PostgreSQL database
|
||||
- Redis cache and Celery broker
|
||||
- pgAdmin database administration
|
||||
- FileBrowser file management
|
||||
- **Docker Deployment** (`docker-compose.app.yml`)
|
||||
- Multi-container setup for development
|
||||
- Services: PostgreSQL, Redis, Django backend, Celery worker, Celery beat
|
||||
- Volume persistence for database and media
|
||||
- Network isolation
|
||||
|
||||
- **Database** (PostgreSQL 14+)
|
||||
- Multi-tenant data model with account isolation
|
||||
- Optimized indexes for common queries
|
||||
- JSON fields for flexible configuration storage
|
||||
- Database migrations system
|
||||
|
||||
- **Task Queue** (Celery + Redis)
|
||||
- Redis as message broker
|
||||
- Celery worker for async tasks
|
||||
- Celery beat for scheduled tasks
|
||||
- Progress tracking with task state updates
|
||||
|
||||
### Documentation
|
||||
- **Master Documentation** (`master-docs/`)
|
||||
- Complete architecture documentation
|
||||
- API reference with endpoint details
|
||||
- Frontend and backend implementation guides
|
||||
- WordPress plugin integration guide
|
||||
|
||||
#### Documentation Files Created
|
||||
- `docs/00-DOCUMENTATION-MANAGEMENT.md` - Documentation and changelog management system
|
||||
- `docs/01-TECH-STACK-AND-INFRASTRUCTURE.md` - Technology stack and infrastructure
|
||||
- `docs/02-APPLICATION-ARCHITECTURE.md` - Application architecture with workflows
|
||||
- `docs/03-FRONTEND-ARCHITECTURE.md` - Frontend architecture documentation
|
||||
- `docs/04-BACKEND-IMPLEMENTATION.md` - Backend implementation reference
|
||||
- `docs/05-AI-FRAMEWORK-IMPLEMENTATION.md` - AI framework implementation reference
|
||||
- `docs/06-FUNCTIONAL-BUSINESS-LOGIC.md` - Functional business logic documentation
|
||||
- **Project Documentation**
|
||||
- `MASTER_REFERENCE.md` - Complete system architecture and navigation
|
||||
- `README.md` - Quick start and setup guide
|
||||
- `CHANGELOG.md` - This file
|
||||
|
||||
#### Documentation Features
|
||||
- Complete workflow documentation
|
||||
- Feature completeness
|
||||
- No code snippets (workflow-focused)
|
||||
- Accurate state reflection
|
||||
- Cross-referenced documents
|
||||
- Self-explaining structure for AI agents
|
||||
### Changed
|
||||
- N/A (Initial release)
|
||||
|
||||
### Deprecated
|
||||
- N/A (Initial release)
|
||||
|
||||
### Removed
|
||||
- N/A (Initial release)
|
||||
|
||||
### Fixed
|
||||
- N/A (Initial release)
|
||||
|
||||
### Security
|
||||
- JWT token authentication with 15-minute expiry and refresh tokens
|
||||
- Secure API key storage in WordPress using encryption helpers
|
||||
- CSRF protection on all forms
|
||||
- SQL injection prevention via Django ORM
|
||||
- XSS protection via Django template escaping
|
||||
- HTTPS enforcement in production
|
||||
- Account isolation at database level with automatic filtering
|
||||
- Permission-based access control with role matrix
|
||||
- Rate limiting to prevent abuse
|
||||
- Request ID tracking for audit trails
|
||||
|
||||
---
|
||||
|
||||
## Version History
|
||||
|
||||
### Current Version: 1.0.0
|
||||
|
||||
**Status**: Production
|
||||
**Date**: 2025-01-XX
|
||||
|
||||
### Version Format
|
||||
|
||||
- **MAJOR**: Breaking changes, major feature additions, architecture changes
|
||||
- **MINOR**: New features, new modules, significant enhancements
|
||||
- **PATCH**: Bug fixes, small improvements, documentation updates
|
||||
|
||||
### Version Update Rules
|
||||
|
||||
1. **MAJOR**: Only updated when user confirms major release
|
||||
2. **MINOR**: Updated when user confirms new feature is complete
|
||||
3. **PATCH**: Updated when user confirms bug fix is complete
|
||||
|
||||
**IMPORTANT**: Never update version without user confirmation.
|
||||
- **1.0.0** (2025-11-24) - Initial release with complete feature set
|
||||
|
||||
---
|
||||
|
||||
## Planned Features
|
||||
## Versioning Strategy
|
||||
|
||||
### In Progress
|
||||
- Planner Dashboard enhancement with KPIs
|
||||
- Automation & CRON tasks
|
||||
- Advanced analytics
|
||||
- **Major version** (X.0.0) - Breaking changes, major architectural changes
|
||||
- **Minor version** (1.X.0) - New features, new modules, backward compatible
|
||||
- **Patch version** (1.0.X) - Bug fixes, minor improvements, documentation updates
|
||||
|
||||
### Future
|
||||
- Analytics module enhancements
|
||||
- Advanced scheduling features
|
||||
---
|
||||
|
||||
## Upgrade Notes
|
||||
|
||||
### Upgrading to 1.0.0
|
||||
This is the initial release. No upgrade path required.
|
||||
|
||||
Future upgrade notes will be documented here for each version.
|
||||
|
||||
---
|
||||
|
||||
## Future Roadmap
|
||||
|
||||
Planned features and improvements (subject to change):
|
||||
|
||||
- Enhanced analytics and reporting
|
||||
- Additional AI model integrations
|
||||
- Stripe payment integration
|
||||
- Plan limits enforcement
|
||||
- Advanced reporting
|
||||
- Advanced automation workflows
|
||||
- Mobile app support
|
||||
- API documentation (Swagger/OpenAPI)
|
||||
- Unit and integration tests for unified API
|
||||
- API webhooks
|
||||
- Collaborative editing features
|
||||
- Multi-language support
|
||||
|
||||
See project board for current priorities and development status.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
**Note:** This changelog is maintained according to [Keep a Changelog](https://keepachangelog.com/) principles and only updated after user confirmation of completed features and fixes.
|
||||
|
||||
- All features are documented in detail in the respective documentation files
|
||||
- Workflows are complete and accurate
|
||||
- System is production-ready
|
||||
- Documentation is maintained and updated regularly
|
||||
- Changelog is only updated after user confirmation
|
||||
|
||||
---
|
||||
|
||||
**For AI Agents**: Before making any changes, read `docs/00-DOCUMENTATION-MANAGEMENT.md` for complete guidelines on versioning, changelog management, and DRY principles.
|
||||
|
||||
Reference in New Issue
Block a user