Implement plugin marketplace backend with database
Some checks failed
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Some checks failed
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Marketplace service: - Added Plugin model to database schema (id, name, description, author, type, version, ipfs_cid, metadata, status, created_at, updated_at, download_count, rating) - Added list_plugins() service method with type and status filters - Added register_plugin() service method - Updated GET /v1/marketplace/plugins to use database instead of mock data - Added POST /v1/marketplace/plugins endpoint for plugin registration - Created plugin table in aitbc_marketplace database Replaces mock plugin data with real database-backed plugin marketplace
This commit is contained in:
@@ -39,3 +39,22 @@ class MarketplaceBid(SQLModel, table=True):
|
||||
notes: str | None = Field(default=None)
|
||||
status: str = Field(default="pending", nullable=False)
|
||||
submitted_at: datetime = Field(default_factory=datetime.utcnow, nullable=False, index=True)
|
||||
|
||||
|
||||
class Plugin(SQLModel, table=True):
|
||||
__tablename__ = "plugin"
|
||||
__table_args__ = {"extend_existing": True}
|
||||
|
||||
id: str = Field(default_factory=lambda: uuid4().hex, primary_key=True)
|
||||
name: str = Field(index=True)
|
||||
description: str = Field(default="")
|
||||
author: str = Field(default="")
|
||||
type: str = Field(default="cli", index=True) # cli, web, blockchain, ai
|
||||
version: str = Field(default="1.0.0")
|
||||
ipfs_cid: str | None = Field(default=None, index=True) # IPFS CID for plugin code
|
||||
metadata: dict = Field(default_factory=dict, sa_column=Column(JSON, nullable=False))
|
||||
status: str = Field(default="pending", index=True) # pending, approved, rejected
|
||||
created_at: datetime = Field(default_factory=datetime.utcnow, nullable=False, index=True)
|
||||
updated_at: datetime = Field(default_factory=datetime.utcnow, nullable=False)
|
||||
download_count: int = Field(default=0)
|
||||
rating: float = Field(default=0.0)
|
||||
|
||||
@@ -249,46 +249,35 @@ async def get_analytics(
|
||||
@app.get("/v1/marketplace/plugins")
|
||||
async def get_plugins(
|
||||
type: str | None = None,
|
||||
status: str = "approved",
|
||||
svc: MarketplaceService = Depends(get_marketplace_service),
|
||||
):
|
||||
"""Get marketplace plugins"""
|
||||
try:
|
||||
logger.info(f"GET /v1/marketplace/plugins called with type={type}")
|
||||
# Return mock plugin data for now
|
||||
plugins = [
|
||||
{
|
||||
"id": "plugin_001",
|
||||
"name": "cli_enhancer",
|
||||
"type": "cli",
|
||||
"author": "AITBC Team",
|
||||
"description": "Enhances CLI with additional commands",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"id": "plugin_002",
|
||||
"name": "web_dashboard",
|
||||
"type": "web",
|
||||
"author": "AITBC Team",
|
||||
"description": "Web dashboard plugin for monitoring",
|
||||
"version": "1.2.0"
|
||||
},
|
||||
{
|
||||
"id": "plugin_003",
|
||||
"name": "security_scanner",
|
||||
"type": "blockchain",
|
||||
"author": "Security Team",
|
||||
"description": "Security scanning plugin for blockchain",
|
||||
"version": "0.9.0"
|
||||
}
|
||||
]
|
||||
if type:
|
||||
plugins = [p for p in plugins if p.get("type") == type]
|
||||
logger.info(f"GET /v1/marketplace/plugins called with type={type}, status={status}")
|
||||
plugins = await svc.list_plugins(type=type, status=status)
|
||||
return {"plugins": plugins}
|
||||
except Exception as e:
|
||||
logger.error(f"Error in GET /v1/marketplace/plugins: {type(e).__name__}: {str(e)}")
|
||||
raise
|
||||
|
||||
|
||||
@app.post("/v1/marketplace/plugins")
|
||||
async def register_plugin(
|
||||
plugin_data: dict,
|
||||
svc: MarketplaceService = Depends(get_marketplace_service),
|
||||
):
|
||||
"""Register a new plugin"""
|
||||
try:
|
||||
logger.info(f"POST /v1/marketplace/plugins called with data keys: {plugin_data.keys()}")
|
||||
result = await svc.register_plugin(plugin_data)
|
||||
logger.info(f"POST /v1/marketplace/plugins registered plugin with id: {result['id']}")
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"Error in POST /v1/marketplace/plugins: {type(e).__name__}: {str(e)}")
|
||||
raise
|
||||
|
||||
|
||||
@app.post("/v1/transactions")
|
||||
async def submit_transaction(transaction_data: dict, session: AsyncSession = Depends(get_session_dep)):
|
||||
"""Submit marketplace transaction"""
|
||||
|
||||
@@ -207,3 +207,58 @@ class MarketplaceService:
|
||||
"total_capacity": total_capacity,
|
||||
"average_price": round(float(avg_price), 2),
|
||||
}
|
||||
|
||||
async def list_plugins(self, type: str | None = None, status: str = "approved") -> list[dict]:
|
||||
"""List plugins from database"""
|
||||
from sqlalchemy import select
|
||||
from .domain.marketplace import Plugin
|
||||
|
||||
try:
|
||||
stmt = select(Plugin)
|
||||
if type:
|
||||
stmt = stmt.where(Plugin.type == type)
|
||||
if status:
|
||||
stmt = stmt.where(Plugin.status == status)
|
||||
stmt = stmt.order_by(Plugin.created_at.desc())
|
||||
|
||||
result = await self.session.execute(stmt)
|
||||
plugins = result.scalars().all()
|
||||
|
||||
return [
|
||||
{
|
||||
"id": p.id,
|
||||
"name": p.name,
|
||||
"description": p.description,
|
||||
"author": p.author,
|
||||
"type": p.type,
|
||||
"version": p.version,
|
||||
"ipfs_cid": p.ipfs_cid,
|
||||
"status": p.status,
|
||||
"download_count": p.download_count,
|
||||
"rating": p.rating,
|
||||
"created_at": p.created_at.isoformat() if p.created_at else None,
|
||||
}
|
||||
for p in plugins
|
||||
]
|
||||
except Exception as e:
|
||||
logger.error(f"Error in list_plugins: {type(e).__name__}: {str(e)}")
|
||||
raise
|
||||
|
||||
async def register_plugin(self, plugin_data: dict) -> dict:
|
||||
"""Register a new plugin"""
|
||||
from .domain.marketplace import Plugin
|
||||
|
||||
try:
|
||||
plugin = Plugin(**plugin_data)
|
||||
self.session.add(plugin)
|
||||
await self.session.commit()
|
||||
await self.session.refresh(plugin)
|
||||
logger.info(f"Registered plugin with id: {plugin.id}")
|
||||
return {
|
||||
"id": plugin.id,
|
||||
"name": plugin.name,
|
||||
"status": plugin.status,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Error in register_plugin: {type(e).__name__}: {str(e)}")
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user