diff --git a/ddpui/api/admin_portal/__init__.py b/ddpui/api/admin_portal/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ddpui/api/admin_portal/organizations_api.py b/ddpui/api/admin_portal/organizations_api.py new file mode 100644 index 000000000..02c467774 --- /dev/null +++ b/ddpui/api/admin_portal/organizations_api.py @@ -0,0 +1,42 @@ +from ninja import Router +from django.http import Http404 +from ddpui.models.org import Org + +admin_org_router = Router() + + +@admin_org_router.get("/v1/organizations") +@admin_org_router.get("/v1/organizations/") +def get_admin_organizations(request, name: str = None): + """ + List organizations with optional filtering + """ + queryset = Org.objects.all() + + if name: + queryset = queryset.filter(name__icontains=name) + + orgs = queryset.values("id", "name", "slug") + + return { + "success": True, + "count": queryset.count(), + "data": list(orgs) + } + + +@admin_org_router.get("/v1/organizations/{org_id}") +@admin_org_router.get("/v1/organizations/{org_id}/") +def get_single_org(request, org_id: int): + """ + Get single organization by ID + """ + org = Org.objects.filter(id=org_id).values("id", "name", "slug").first() + + if not org: + raise Http404("Organization not found") + + return { + "success": True, + "data": org + } \ No newline at end of file diff --git a/ddpui/migrations/0085_syncstats.py b/ddpui/migrations/0085_syncstats.py index f395f02c1..887804caf 100644 --- a/ddpui/migrations/0085_syncstats.py +++ b/ddpui/migrations/0085_syncstats.py @@ -25,10 +25,11 @@ class Migration(migrations.Migration): ("connection_id", models.CharField(max_length=36)), ("attempt", models.IntegerField(default=0)), ("status", models.TextField()), - ( + ( "sync_type", models.CharField( - choices=[("manual", "manual"), ("orchestrate", "orchestrate")] + max_length=20, + choices=[("manual", "manual"), ("orchestrate", "orchestrate")], ), ), ("sync_time", models.DateTimeField()), diff --git a/ddpui/models/airbyte.py b/ddpui/models/airbyte.py index 49595562d..127a94933 100644 --- a/ddpui/models/airbyte.py +++ b/ddpui/models/airbyte.py @@ -8,11 +8,17 @@ class SyncStats(models.Model): """single table to track connection sync stats""" org = models.ForeignKey(Org, on_delete=models.CASCADE) - connection_id = models.CharField(max_length=36) + connection_id = models.CharField(max_length=50) job_id = models.IntegerField(null=True) attempt = models.IntegerField(default=0) status = models.TextField() - sync_type = models.CharField(choices=[("manual", "manual"), ("orchestrate", "orchestrate")]) + + # ✅ FIXED LINE (added max_length) + sync_type = models.CharField( + max_length=20, + choices=[("manual", "manual"), ("orchestrate", "orchestrate")] + ) + sync_time = models.DateTimeField() sync_duration_s = models.BigIntegerField(default=0) sync_records = models.BigIntegerField(default=0) @@ -66,7 +72,7 @@ class AirbyteJob(models.Model): started_at = models.DateTimeField(null=True) # because the api spec says this will be optional ended_at = models.DateTimeField( null=True - ) # when the job ended; can be null if we pull or sync an ongonig job + ) # when the job ended; can be null if we pull or sync an ongoing job created_at = models.DateTimeField() # when the job was created in airbyte updated_at = models.DateTimeField(auto_now=True) # when the django record was last updated @@ -109,4 +115,4 @@ def latest_failed_attempt_id(self): if failed_attempts: return max(failed_attempts, key=lambda x: x["id"])["id"] - return None + return None \ No newline at end of file diff --git a/ddpui/routes.py b/ddpui/routes.py index fa95799f8..46e1bd095 100644 --- a/ddpui/routes.py +++ b/ddpui/routes.py @@ -24,15 +24,14 @@ from ddpui.api.filter_api import filter_router from ddpui.api.public_api import public_router from ddpui.api.report_api import report_router - +from ddpui.api.admin_portal.organizations_api import admin_org_router src_api = NinjaAPI( urls_namespace="api", title="Dalgo backend apis", description="Open source ELT orchestrator", docs_url="/api/docs", - # auth=auth.CustomAuthMiddleware(), - auth=auth.CustomJwtAuthMiddleware(), + auth=auth.CustomJwtAuthMiddleware() ) @@ -108,7 +107,7 @@ def ninja_default_error_handler( src_api.add_router("/api/dashboards/", dashboard_native_router) src_api.add_router("/api/filters/", filter_router) src_api.add_router("/api/reports/", report_router) - +src_api.add_router("/api/admin/", admin_org_router) # Public API without authentication public_api = NinjaAPI( urls_namespace="public-api",