From d57333947707a5888bb298a3368b6b99fe816eca Mon Sep 17 00:00:00 2001 From: ngovinh2k2 Date: Wed, 13 May 2026 11:00:07 +0700 Subject: [PATCH 1/2] feat: add template field for organization model --- .../migrations/0002_organization_template.py | 26 +++++++++++++++++++ apps/organization/models.py | 4 +++ .../management/commands/init_organization.py | 12 ++++++--- docker-entrypoint.sh | 2 ++ 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 apps/organization/migrations/0002_organization_template.py diff --git a/apps/organization/migrations/0002_organization_template.py b/apps/organization/migrations/0002_organization_template.py new file mode 100644 index 0000000..d52de6d --- /dev/null +++ b/apps/organization/migrations/0002_organization_template.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.6 on 2026-05-13 04:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("organization", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="organization", + name="template", + field=models.CharField( + blank=True, + choices=[ + ("smart_building", "Smart Building"), + ("smart_fleet_monitor", "Smart Fleet Monitor"), + ], + max_length=256, + null=True, + ), + ), + ] diff --git a/apps/organization/models.py b/apps/organization/models.py index 8860cce..086bcf5 100644 --- a/apps/organization/models.py +++ b/apps/organization/models.py @@ -1,5 +1,6 @@ import logging +from common.apps.organization.constants import OrganizationTemplate from common.models.base_model import BaseModel from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator @@ -32,3 +33,6 @@ class Organization(BaseModel): rabbitmq_provisioned_at = models.DateTimeField( blank=True, null=True, help_text="When RabbitMQ resources were provisioned" ) + template = models.CharField( + max_length=256, choices=OrganizationTemplate.choices, blank=True, null=True + ) diff --git a/bootstrap_service/management/commands/init_organization.py b/bootstrap_service/management/commands/init_organization.py index 3e029db..da8eff0 100644 --- a/bootstrap_service/management/commands/init_organization.py +++ b/bootstrap_service/management/commands/init_organization.py @@ -55,6 +55,7 @@ def _get_config(self, **kwargs): return { "org_name": kwargs.get("org_name") or os.getenv("ORG_NAME"), "org_slug": kwargs.get("org_slug") or os.getenv("ORG_SLUG"), + "org_template": kwargs.get("org_template") or os.getenv("ORG_TEMPLATE"), "owner_email": kwargs.get("owner_email") or os.getenv("OWNER_EMAIL"), "owner_password": kwargs.get("owner_password") or os.getenv("OWNER_PASSWORD"), @@ -136,7 +137,7 @@ def _create_organization_with_roles(self, org_id, org_name, org_slug, result): self.stdout.write(self.style.SUCCESS("Created default roles")) return organization, owner_role - def _send_celery_task(self, org_id, org_name, org_slug, user): + def _send_celery_task(self, org_id, org_name, org_slug, org_template, user): """Send initialization task to Celery.""" send_task( name="new_organization", @@ -145,6 +146,7 @@ def _send_celery_task(self, org_id, org_name, org_slug, user): "name": org_name, "slug_name": org_slug, "is_active": True, + "template": org_template, "owner": model_to_dict( user, fields=[ @@ -198,7 +200,11 @@ def _delete_organization(self, provisioner, organization): def handle(self, *args, **kwargs): config = self._get_config(**kwargs) - org_name, org_slug = config["org_name"], config["org_slug"] + org_name, org_slug, org_template = ( + config["org_name"], + config["org_slug"], + config.get("org_template", ""), + ) owner_email, owner_password = config["owner_email"], config["owner_password"] encrypted_password = make_password(owner_password) org_id = str(uuid.uuid4()) @@ -235,7 +241,7 @@ def handle(self, *args, **kwargs): # Publish organization event self._publish_org_event(org_id, org_slug, org_name, result) - self._send_celery_task(org_id, org_name, org_slug, user) + self._send_celery_task(org_id, org_name, org_slug, org_template, user) else: self.stdout.write( self.style.WARNING( diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index baf24a1..6066a08 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -5,6 +5,7 @@ echo "Organization Service Starting..." echo "ORG_NAME: ${ORG_NAME:-not set}" echo "ORG_SLUG: spacedf" echo "OWNER_EMAIL: ${OWNER_EMAIL:-not set}" +echo "ORG_TEMPLATE: ${ORG_TEMPLATE:-not set}" echo "Waiting for RabbitMQ AMQP on rabbitmq:5672..." until nc -z rabbitmq 5672; do @@ -33,6 +34,7 @@ echo "Running organization initialization..." python manage.py init_organization \ --org-name="${ORG_NAME}" \ --org-slug="spacedf" \ + --org-template="${ORG_TEMPLATE}" \ --owner-email="${OWNER_EMAIL}" \ --owner-password="${OWNER_PASSWORD}" From d1e8789cad0306ea5e59e1537e1bd403c3041ed9 Mon Sep 17 00:00:00 2001 From: ngovinh2k2 Date: Tue, 19 May 2026 09:40:39 +0700 Subject: [PATCH 2/2] fix: prevent crashing using itemgetter --- apps/authentication/services.py | 7 +++---- apps/organization/migrations/0002_organization_template.py | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/authentication/services.py b/apps/authentication/services.py index 708ca08..7d405eb 100644 --- a/apps/authentication/services.py +++ b/apps/authentication/services.py @@ -1,4 +1,3 @@ -from operator import itemgetter from typing import Literal import requests @@ -64,9 +63,9 @@ def handle_access_token(access_token, provider: Literal["GOOGLE"]): response = requests.post(url=info_url, headers=headers, timeout=10) response.raise_for_status() user_info_dict = response.json() - given_name, family_name, email = itemgetter("given_name", "family_name", "email")( - user_info_dict - ) + given_name = user_info_dict.get("given_name", "") + family_name = user_info_dict.get("family_name", "") + email = user_info_dict["email"] root_user, is_created = RootUser.objects.get_or_create( email=email, ) diff --git a/apps/organization/migrations/0002_organization_template.py b/apps/organization/migrations/0002_organization_template.py index d52de6d..c404cc6 100644 --- a/apps/organization/migrations/0002_organization_template.py +++ b/apps/organization/migrations/0002_organization_template.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("organization", "0001_initial"), ]