diff --git a/backend/core/settings.py b/backend/core/settings.py index 2c6afa9..65fc5f7 100644 --- a/backend/core/settings.py +++ b/backend/core/settings.py @@ -47,6 +47,8 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', + 'tasks', + 'users', 'rest_framework', 'corsheaders', diff --git a/backend/tasks/__init__.py b/backend/tasks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tasks/admin.py b/backend/tasks/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/tasks/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/tasks/apps.py b/backend/tasks/apps.py new file mode 100644 index 0000000..3ff3ab3 --- /dev/null +++ b/backend/tasks/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class TasksConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'tasks' diff --git a/backend/tasks/migrations/0001_initial.py b/backend/tasks/migrations/0001_initial.py new file mode 100644 index 0000000..e60ea87 --- /dev/null +++ b/backend/tasks/migrations/0001_initial.py @@ -0,0 +1,83 @@ +# Generated by Django 4.2.6 on 2023-10-28 15:50 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Reminder', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('startDate', models.DateField(blank=True, null=True)), + ('time', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name='UserNotification', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('LEVEL_UP', 'Level Up'), ('DEATH', 'Death')], max_length=255)), + ('data', models.JSONField(default=dict)), + ('seen', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='Transaction', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('currency', models.CharField(choices=[('gold', 'Gold')], max_length=12)), + ('transaction_type', models.CharField(choices=[('buy_gold', 'Buy Gold'), ('spend', 'Spend'), ('debug', 'Debug'), ('force_update_gold', 'Force Update Gold')], max_length=24)), + ('description', models.TextField(blank=True)), + ('amount', models.FloatField(default=0)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.CharField(choices=[('daily', 'Daily'), ('habit', 'Habit'), ('todo', 'Todo'), ('Long Term Goal', 'Long Term Goal')], default='habit', max_length=15)), + ('title', models.TextField()), + ('notes', models.TextField(default='')), + ('completed', models.BooleanField(default=False)), + ('exp', models.FloatField(default=0)), + ('priority', models.FloatField(default=1, validators=[django.core.validators.MinValueValidator(0.1), django.core.validators.MaxValueValidator(2)])), + ('difficulty', models.PositiveSmallIntegerField(choices=[(1, 'Easy'), (2, 'Normal'), (3, 'Hard'), (4, 'Very Hard'), (5, 'Devil')], unique=True)), + ('attribute', models.CharField(choices=[('str', 'Strength'), ('int', 'Intelligence'), ('end', 'Endurance'), ('per', 'Perception'), ('luck', 'Luck')], default='str', max_length=15)), + ('challenge', models.BooleanField(default=False)), + ('fromSystem', models.BooleanField(default=False)), + ('creation_date', models.DateTimeField(auto_now_add=True)), + ('last_update', models.DateTimeField(auto_now=True)), + ('reminders', models.ManyToManyField(to='tasks.reminder')), + ('tags', models.ManyToManyField(to='tasks.tag')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Subtask', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('description', models.TextField()), + ('completed', models.BooleanField(default=False)), + ('parent_task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tasks.task')), + ], + ), + ] diff --git a/backend/tasks/migrations/__init__.py b/backend/tasks/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tasks/models.py b/backend/tasks/models.py new file mode 100644 index 0000000..ca8c7e0 --- /dev/null +++ b/backend/tasks/models.py @@ -0,0 +1,157 @@ +from django.db import models +from django.conf import settings +from django.core import validators + + +class Reminder(models.Model): + """ + Represents a reminder associated with a task. + Fields: + - startDate: The optional date for which the reminder is set. + - time: The time at which the reminder is triggered. + """ + startDate = models.DateField(null=True, blank=True) + time = models.DateTimeField() + +class Tag(models.Model): + """ + Represents a tag that can be associated with tasks. + Fields: + - name: The unique name of the tag. + """ + name = models.CharField(max_length=255) + +class Task(models.Model): + """ + Represents a task, such as Habit, Daily, Todo, or Reward. + Fields: + - type: The type of the tasks + - title: Title of the task. + - notes: Optional additional notes for the task. + - tags: Associated tags for the task. + - completed: A boolean field indicating whether the task is completed. + - exp: The experience values user will get from the task. + - priority: The priority of the task (range: 0.1 to 2). + - difficulty: The difficulty of the task (range: 1 to 5). + - attribute: The attribute linked to the task + - user: The user who owns the task. + - challenge: Associated challenge (optional). + - reminders: A Many-to-Many relationship with Reminder. + - fromSystem: A boolean field indicating if the task is from System. + - creation_date: Creation date of the task. + - last_update: Last updated date of the task. + """ + TASK_TYPES = [ + ('daily', 'Daily'), + ('habit', 'Habit'), + ('todo', 'Todo'), + ('Long Term Goal', 'Long Term Goal'), + ] + + DIFFICULTY_CHOICES = [ + (1, 'Easy'), + (2, 'Normal'), + (3, 'Hard'), + (4, 'Very Hard'), + (5, 'Devil'), + ] + + type = models.CharField(max_length=15, choices=TASK_TYPES, default='habit') + title = models.TextField() + notes = models.TextField(default='') + tags = models.ManyToManyField(Tag) + completed = models.BooleanField(default=False) + exp = models.FloatField(default=0) + priority = models.FloatField(default=1, validators=[ + validators.MinValueValidator(0.1), + validators.MaxValueValidator(2), + ]) + difficulty = models.PositiveSmallIntegerField(choices=DIFFICULTY_CHOICES, unique=True) + attribute = models.CharField(max_length=15, choices=[ + ('str', 'Strength'), + ('int', 'Intelligence'), + ('end', 'Endurance'), + ('per', 'Perception'), + ('luck', 'Luck'), + ], default='str') + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + challenge = models.BooleanField(default=False) + reminders = models.ManyToManyField(Reminder) + fromSystem = models.BooleanField(default=False) + creation_date = models.DateTimeField(auto_now_add=True) + last_update = models.DateTimeField(auto_now=True) + + +class Subtask(models.Model): + """ + Represents a subtask associated with a task. + - description: Description of the subtask. + - completed: A boolean field indicating whether the subtask is completed. + - parent_task: The parent task of the subtask. + """ + description = models.TextField() + completed = models.BooleanField(default=False) + parent_task = models.ForeignKey(Task, on_delete=models.CASCADE) + + +class UserNotification(models.Model): + """ + Represents a user notification. + Fields: + - type: The type of the notification (e.g., 'NEW_CHAT_MESSAGE'). + - data: JSON data associated with the notification. + - seen: A boolean field indicating whether the notification has been seen. + """ + NOTIFICATION_TYPES = ( + ('LEVEL_UP', 'Level Up'), + ('DEATH', 'Death'), + ) + + type = models.CharField(max_length=255, choices=[type for type in NOTIFICATION_TYPES]) + data = models.JSONField(default=dict) + seen = models.BooleanField(default=False) + + @staticmethod + def clean_notification(notifications): + """ + Cleanup function for removing corrupt notification data: + - Removes notifications with null or missing id or type. + """ + if not notifications: + return notifications + + filtered_notifications = [] + + for notification in notifications: + if notification.id is None or notification.type is None: + continue + + return filtered_notifications + + +class Transaction(models.Model): + """ + Represents a transaction involving currencies in the system. + Fields: + - currency: The type of currency used in the transaction + - transactionType: The type of the transaction + - description: Additional text. + - amount: The transaction amount. + - user: The user involved in the transaction. + """ + CURRENCIES = (('gold', 'Gold'),) + TRANSACTION_TYPES = ( + ('buy_gold', 'Buy Gold'), + ('spend', 'Spend'), + ('debug', 'Debug'), + ('force_update_gold', 'Force Update Gold'), + ) + + currency = models.CharField(max_length=12, choices=CURRENCIES) + transaction_type = models.CharField(max_length=24, choices=TRANSACTION_TYPES) + description = models.TextField(blank=True) + amount = models.FloatField(default=0) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + + def __str__(self): + return f"Transaction ({self.id})" \ No newline at end of file diff --git a/backend/tasks/tests.py b/backend/tasks/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/tasks/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/tasks/views.py b/backend/tasks/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backend/tasks/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/backend/users/models.py b/backend/users/models.py index 03d6e12..e473572 100644 --- a/backend/users/models.py +++ b/backend/users/models.py @@ -26,3 +26,17 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): def __str__(self): # String representation of the user return self.username + + +# class UserStats(models.Model): +# """ +# Represents User Profiles and Attributes. +# Fields: +# - health: health points of the user. +# - gold: gold points of the user. +# - experience: experience points of the user. +# """ +# user = models.OneToOneField(CustomUser, on_delete=models.CASCADE) +# health = models.IntegerField(default=100) +# gold = models.IntegerField(default=0) +# experience = models.FloatField(default=0) \ No newline at end of file