Add project scaffolding and documentation

Add .env.example with configuration for database, Redis, security, SMTP, workers, and plugins. Add .gitignore for Python, Node.js, Next.js, Docker volumes, and IDE files. Add MIT License. Update README.md with feature overview, quick start guide, architecture description, plugin system documentation, security details, backup/restore instructions, and developer setup. Add Alembic configuration files and placeholder directories for API, web, worker, and plugin components
This commit is contained in:
2026-06-21 09:31:47 +02:00
parent cfeeccbf53
commit d694c8b8e3
197 changed files with 8583 additions and 56 deletions
+68
View File
@@ -0,0 +1,68 @@
import uuid
from abc import ABC, abstractmethod
from typing import Any
import httpx
from apps.api.src.models.plugin_instance import PluginInstance
from apps.api.src.models.service_connection import ServiceConnection
from apps.api.src.security.encryption import decrypt_dict
from apps.api.src.services import secret_service
class PluginContext:
def __init__(
self,
instance: PluginInstance,
connection: ServiceConnection | None,
credentials: dict[str, Any] | None,
http_client: httpx.AsyncClient,
):
self.instance = instance
self.connection = connection
self.credentials = credentials or {}
self.http_client = http_client
class PluginConnector(ABC):
id: str = ""
name: str = ""
default_timeout: float = 30.0
def __init__(self, context: PluginContext):
self.context = context
async def get_credentials(self) -> dict[str, Any]:
return self.context.credentials
def get_client(self) -> httpx.AsyncClient:
return self.context.http_client
@abstractmethod
async def healthcheck(self) -> dict[str, Any]:
pass
@abstractmethod
async def fetch_widget_data(self, widget_type: str, settings: dict[str, Any]) -> dict[str, Any]:
pass
async def close(self) -> None:
pass
async def build_context(
db,
instance: PluginInstance,
) -> PluginContext:
connection = instance.service_connection
credentials = None
if connection and connection.credentials_id:
secret_value = await secret_service.decrypt_secret_value(db, connection.credentials_id)
credentials = decrypt_dict(secret_value)
client = httpx.AsyncClient(
verify=connection.verify_tls if connection else True,
timeout=connection.timeout_seconds if connection else 30,
follow_redirects=False,
)
return PluginContext(instance, connection, credentials, client)