account, schduels, timezone profile and many imporant updates
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('igny8_core_auth', '0031_drop_all_blueprint_tables'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='account',
|
||||
name='account_timezone',
|
||||
field=models.CharField(default='UTC', help_text='IANA timezone name', max_length=64),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='account',
|
||||
name='timezone_mode',
|
||||
field=models.CharField(choices=[('country', 'Country'), ('manual', 'Manual')], default='country', help_text='Timezone selection mode', max_length=20),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='account',
|
||||
name='timezone_offset',
|
||||
field=models.CharField(blank=True, default='', help_text='Optional UTC offset label', max_length=10),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,28 @@
|
||||
# Generated by Django 5.2.9 on 2026-01-19 00:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('igny8_core_auth', '0032_add_account_timezone_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='historicalaccount',
|
||||
name='account_timezone',
|
||||
field=models.CharField(default='UTC', max_length=64, help_text='IANA timezone name'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalaccount',
|
||||
name='timezone_mode',
|
||||
field=models.CharField(choices=[('country', 'Country'), ('manual', 'Manual')], default='country', max_length=20, help_text='Timezone selection mode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalaccount',
|
||||
name='timezone_offset',
|
||||
field=models.CharField(blank=True, default='', max_length=10, help_text='Optional UTC offset label'),
|
||||
),
|
||||
]
|
||||
18
backend/igny8_core/auth/migrations/0034_add_user_phone.py
Normal file
18
backend/igny8_core/auth/migrations/0034_add_user_phone.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.9 on 2026-01-19 00:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('igny8_core_auth', '0033_add_account_timezone_history_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='phone',
|
||||
field=models.CharField(blank=True, default='', max_length=30),
|
||||
),
|
||||
]
|
||||
@@ -106,6 +106,16 @@ class Account(SoftDeletableModel):
|
||||
billing_postal_code = models.CharField(max_length=20, blank=True)
|
||||
billing_country = models.CharField(max_length=2, blank=True, help_text="ISO 2-letter country code")
|
||||
tax_id = models.CharField(max_length=100, blank=True, help_text="VAT/Tax ID number")
|
||||
|
||||
# Account timezone (single source of truth for all users/sites)
|
||||
account_timezone = models.CharField(max_length=64, default='UTC', help_text="IANA timezone name")
|
||||
timezone_mode = models.CharField(
|
||||
max_length=20,
|
||||
choices=[('country', 'Country'), ('manual', 'Manual')],
|
||||
default='country',
|
||||
help_text="Timezone selection mode"
|
||||
)
|
||||
timezone_offset = models.CharField(max_length=10, blank=True, default='', help_text="Optional UTC offset label")
|
||||
|
||||
# Monthly usage tracking (reset on billing cycle)
|
||||
usage_ahrefs_queries = models.IntegerField(default=0, validators=[MinValueValidator(0)], help_text="Ahrefs queries used this month")
|
||||
@@ -922,6 +932,7 @@ class User(AbstractUser):
|
||||
account = models.ForeignKey('igny8_core_auth.Account', on_delete=models.CASCADE, related_name='users', null=True, blank=True, db_column='tenant_id')
|
||||
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='viewer')
|
||||
email = models.EmailField(_('email address'), unique=True)
|
||||
phone = models.CharField(max_length=30, blank=True, default='')
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@ class AccountSerializer(serializers.ModelSerializer):
|
||||
fields = [
|
||||
'id', 'name', 'slug', 'owner', 'plan', 'plan_id',
|
||||
'credits', 'status', 'payment_method',
|
||||
'subscription', 'billing_country', 'created_at'
|
||||
'subscription', 'billing_country',
|
||||
'account_timezone', 'timezone_mode', 'timezone_offset',
|
||||
'created_at'
|
||||
]
|
||||
read_only_fields = ['owner', 'created_at']
|
||||
|
||||
@@ -270,7 +272,18 @@ class UserSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['id', 'username', 'email', 'role', 'account', 'accessible_sites', 'created_at']
|
||||
fields = [
|
||||
'id',
|
||||
'username',
|
||||
'email',
|
||||
'phone',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'role',
|
||||
'account',
|
||||
'accessible_sites',
|
||||
'created_at',
|
||||
]
|
||||
read_only_fields = ['created_at']
|
||||
|
||||
def get_accessible_sites(self, obj):
|
||||
|
||||
@@ -255,6 +255,25 @@ class UsersViewSet(AccountModelViewSet):
|
||||
serializer = UserSerializer(user)
|
||||
return success_response(data={'user': serializer.data}, request=request)
|
||||
|
||||
@action(detail=False, methods=['get', 'patch'], permission_classes=[IsAuthenticatedAndActive])
|
||||
def me(self, request):
|
||||
"""Get or update the current user profile."""
|
||||
user = request.user
|
||||
|
||||
if request.method == 'PATCH':
|
||||
serializer = UserSerializer(user, data=request.data, partial=True)
|
||||
if not serializer.is_valid():
|
||||
return error_response(
|
||||
error='Validation failed',
|
||||
errors=serializer.errors,
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
serializer.save()
|
||||
|
||||
serializer = UserSerializer(user)
|
||||
return success_response(data={'user': serializer.data}, request=request)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 3. ACCOUNTS - Register each unique organization/user space
|
||||
|
||||
Reference in New Issue
Block a user