From 0d4884a7a0aef3e8087cdebea1623fd82992feab Mon Sep 17 00:00:00 2001 From: ColumnSkunky Date: Mon, 24 Mar 2025 19:45:53 -0700 Subject: [PATCH 1/5] feat: tags to project model --- backend/projects/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/projects/models.py b/backend/projects/models.py index 32148b7..ad36c9d 100644 --- a/backend/projects/models.py +++ b/backend/projects/models.py @@ -1,5 +1,6 @@ from django.db import models from userauth.models import User +from django.contrib.postgres.fields import ArrayField # PROJECTS MODEL class Project(models.Model): @@ -13,6 +14,7 @@ class Project(models.Model): positions = models.JSONField(default=list) image_url = models.ImageField(upload_to="projects/", blank=True, null=True) images = models.JSONField(default=list) + tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) def __str__(self): return self.title From cb4077e0fb457104915d8e72aa64e70d6afa0e0d Mon Sep 17 00:00:00 2001 From: ColumnSkunky Date: Mon, 24 Mar 2025 20:01:47 -0700 Subject: [PATCH 2/5] fix: added tags to migrations --- .../projects/migrations/0006_project_tags.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 backend/projects/migrations/0006_project_tags.py diff --git a/backend/projects/migrations/0006_project_tags.py b/backend/projects/migrations/0006_project_tags.py new file mode 100644 index 0000000..92d41b4 --- /dev/null +++ b/backend/projects/migrations/0006_project_tags.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.6 on 2025-03-25 02:56 + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0005_rename_followers_project_followers_count_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='tags', + field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=225), blank=True, null=True, size=None), + ), + ] From c7c69bf46d9df4d6718c73a6a0c84948e1adebdb Mon Sep 17 00:00:00 2001 From: ColumnSkunky Date: Mon, 24 Mar 2025 21:39:25 -0700 Subject: [PATCH 3/5] feat: uuid implementation, email, full description, updates, wanted and links between user and project --- ...email_project_full_description_and_more.py | 57 +++++++++++++++++++ .../migrations/0008_populate_uuids.py | 20 +++++++ ...ove_project_id_alter_project_project_id.py | 23 ++++++++ backend/projects/models.py | 24 +++++++- ...er_owned_user_projects_alter_user_email.py | 30 ++++++++++ backend/userauth/models.py | 17 +++++- 6 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 backend/projects/migrations/0007_project_email_project_full_description_and_more.py create mode 100644 backend/projects/migrations/0008_populate_uuids.py create mode 100644 backend/projects/migrations/0009_remove_project_id_alter_project_project_id.py create mode 100644 backend/userauth/migrations/0002_user_owned_user_projects_alter_user_email.py diff --git a/backend/projects/migrations/0007_project_email_project_full_description_and_more.py b/backend/projects/migrations/0007_project_email_project_full_description_and_more.py new file mode 100644 index 0000000..3baed1c --- /dev/null +++ b/backend/projects/migrations/0007_project_email_project_full_description_and_more.py @@ -0,0 +1,57 @@ +# Generated by Django 5.1.6 on 2025-03-25 04:35 + +import django.contrib.postgres.fields +import django.db.models.deletion +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0006_project_tags'), + ('userauth', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='email', + field=models.EmailField(blank=True, max_length=254, null=True, unique=True), + ), + migrations.AddField( + model_name='project', + name='full_description', + field=models.CharField(blank=True, max_length=1000, null=True), + ), + migrations.AddField( + model_name='project', + name='members', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='member_of_projects', to='userauth.user'), + ), + migrations.AddField( + model_name='project', + name='other_contact', + field=models.CharField(blank=True, max_length=225, null=True), + ), + migrations.AddField( + model_name='project', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owned_projects', to='userauth.user'), + ), + migrations.AddField( + model_name='project', + name='project_id', + field=models.UUIDField(default=uuid.uuid4, editable=False, null=True), + ), + migrations.AddField( + model_name='project', + name='updates', + field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=540), blank=True, null=True, size=None), + ), + migrations.AddField( + model_name='project', + name='wanted_description', + field=models.CharField(blank=True, max_length=540, null=True), + ), + ] diff --git a/backend/projects/migrations/0008_populate_uuids.py b/backend/projects/migrations/0008_populate_uuids.py new file mode 100644 index 0000000..eda508e --- /dev/null +++ b/backend/projects/migrations/0008_populate_uuids.py @@ -0,0 +1,20 @@ +# Generated by Django 5.1.6 on 2025-03-25 04:36 + +from django.db import migrations +import uuid + +def populate_uuids(apps, schema_editor): + Project = apps.get_model('projects', 'Project') + for project in Project.objects.all(): + project.project_id = uuid.uuid4() + project.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0007_project_email_project_full_description_and_more'), + ] + + operations = [ + migrations.RunPython(populate_uuids), + ] diff --git a/backend/projects/migrations/0009_remove_project_id_alter_project_project_id.py b/backend/projects/migrations/0009_remove_project_id_alter_project_project_id.py new file mode 100644 index 0000000..e8d1dd4 --- /dev/null +++ b/backend/projects/migrations/0009_remove_project_id_alter_project_project_id.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.6 on 2025-03-25 04:38 + +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0008_populate_uuids'), + ] + + operations = [ + migrations.RemoveField( + model_name='project', + name='id', + ), + migrations.AlterField( + model_name='project', + name='project_id', + field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + ] diff --git a/backend/projects/models.py b/backend/projects/models.py index ad36c9d..87b97f7 100644 --- a/backend/projects/models.py +++ b/backend/projects/models.py @@ -1,9 +1,10 @@ from django.db import models from userauth.models import User from django.contrib.postgres.fields import ArrayField - +import uuid # PROJECTS MODEL class Project(models.Model): + project_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) group = models.CharField(max_length=255) match_percentage = models.FloatField() title = models.CharField(max_length=255) @@ -15,6 +16,27 @@ class Project(models.Model): image_url = models.ImageField(upload_to="projects/", blank=True, null=True) images = models.JSONField(default=list) tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) + full_description = models.CharField(max_length=1000, blank=True, null=True) + email = models.EmailField(unique=True, blank=True, null=True) + other_contact = models.CharField(max_length=225, blank=True, null=True) + #discussion = ArrayField(models.CharField(max_length=540), blank=True, null=True) + updates = ArrayField(models.CharField(max_length=540), blank=True, null=True) + wanted_description = models.CharField(max_length=540, blank=True, null=True) + members = models.ForeignKey( + 'userauth.User', + on_delete=models.CASCADE, + related_name='member_of_projects', + null=True, + blank=True + ) + + owner = models.ForeignKey( + 'userauth.User', + on_delete=models.CASCADE, + related_name='owned_projects', + null=True, + blank=True + ) def __str__(self): return self.title diff --git a/backend/userauth/migrations/0002_user_owned_user_projects_alter_user_email.py b/backend/userauth/migrations/0002_user_owned_user_projects_alter_user_email.py new file mode 100644 index 0000000..1916e25 --- /dev/null +++ b/backend/userauth/migrations/0002_user_owned_user_projects_alter_user_email.py @@ -0,0 +1,30 @@ +# Generated by Django 5.1.6 on 2025-03-25 04:35 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0007_project_email_project_full_description_and_more'), + ('userauth', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='owned', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owners', to='projects.project'), + ), + migrations.AddField( + model_name='user', + name='projects', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contributors', to='projects.project'), + ), + migrations.AlterField( + model_name='user', + name='email', + field=models.EmailField(blank=True, max_length=254, null=True, unique=True), + ), + ] diff --git a/backend/userauth/models.py b/backend/userauth/models.py index bd52789..54d1f03 100644 --- a/backend/userauth/models.py +++ b/backend/userauth/models.py @@ -4,12 +4,27 @@ class User(models.Model): auth_id = models.IntegerField(default=999) username = models.CharField(max_length=255, unique=True) - email = models.EmailField(unique=True) + email = models.EmailField(unique=True, blank=True, null=True) institution = models.CharField(max_length=255, blank=True, null=True) followers = models.IntegerField(default=0) likes = models.IntegerField(default=0) position = models.JSONField(default=list) tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) + + projects = models.ForeignKey( + 'projects.Project', + on_delete=models.CASCADE, + related_name='contributors', # good practice to add related_name + null=True, # add null=True if this can be blank + blank=True + ) + owned = models.ForeignKey( + 'projects.Project', + on_delete=models.CASCADE, + related_name='owners', + null=True, + blank=True + ) def __str__(self): return self.username From 4215f9608d64ed886b9351d0f9c2ac4b0fa96cd5 Mon Sep 17 00:00:00 2001 From: Larry La Date: Tue, 25 Mar 2025 21:36:19 -0700 Subject: [PATCH 4/5] feat: refactor fields --- ...interest_tags_project_location_and_more.py | 49 +++++++++++++++++++ ..._remove_project_members_project_members.py | 23 +++++++++ .../migrations/0012_alter_project_members.py | 19 +++++++ .../0013_rename_project_id_project_id.py | 18 +++++++ backend/projects/models.py | 35 +++++++------ backend/projects/urls.py | 2 +- ...rename_tags_user_interest_tags_and_more.py | 34 +++++++++++++ ...emove_user_projects_user_owned_and_more.py | 32 ++++++++++++ backend/userauth/models.py | 18 +++---- 9 files changed, 205 insertions(+), 25 deletions(-) create mode 100644 backend/projects/migrations/0010_rename_tags_project_interest_tags_project_location_and_more.py create mode 100644 backend/projects/migrations/0011_remove_project_members_project_members.py create mode 100644 backend/projects/migrations/0012_alter_project_members.py create mode 100644 backend/projects/migrations/0013_rename_project_id_project_id.py create mode 100644 backend/userauth/migrations/0003_rename_tags_user_interest_tags_and_more.py create mode 100644 backend/userauth/migrations/0004_remove_user_owned_remove_user_projects_user_owned_and_more.py diff --git a/backend/projects/migrations/0010_rename_tags_project_interest_tags_project_location_and_more.py b/backend/projects/migrations/0010_rename_tags_project_interest_tags_project_location_and_more.py new file mode 100644 index 0000000..9f746eb --- /dev/null +++ b/backend/projects/migrations/0010_rename_tags_project_interest_tags_project_location_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 5.1.7 on 2025-03-26 04:24 + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0009_remove_project_id_alter_project_project_id'), + ] + + operations = [ + migrations.RenameField( + model_name='project', + old_name='tags', + new_name='interest_tags', + ), + migrations.AddField( + model_name='project', + name='location', + field=models.JSONField(blank=True, default=list), + ), + migrations.AddField( + model_name='project', + name='skill_tags', + field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=225), blank=True, null=True, size=None), + ), + migrations.AlterField( + model_name='project', + name='group', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AlterField( + model_name='project', + name='image_url', + field=models.ImageField(upload_to='projects/'), + ), + migrations.AlterField( + model_name='project', + name='images', + field=models.JSONField(blank=True, default=list), + ), + migrations.AlterField( + model_name='project', + name='match_percentage', + field=models.FloatField(blank=True, null=True), + ), + ] diff --git a/backend/projects/migrations/0011_remove_project_members_project_members.py b/backend/projects/migrations/0011_remove_project_members_project_members.py new file mode 100644 index 0000000..9fb8480 --- /dev/null +++ b/backend/projects/migrations/0011_remove_project_members_project_members.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.7 on 2025-03-26 04:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0010_rename_tags_project_interest_tags_project_location_and_more'), + ('userauth', '0003_rename_tags_user_interest_tags_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='project', + name='members', + ), + migrations.AddField( + model_name='project', + name='members', + field=models.ManyToManyField(blank=True, null=True, related_name='member_of_projects', to='userauth.user'), + ), + ] diff --git a/backend/projects/migrations/0012_alter_project_members.py b/backend/projects/migrations/0012_alter_project_members.py new file mode 100644 index 0000000..46254bb --- /dev/null +++ b/backend/projects/migrations/0012_alter_project_members.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-03-26 04:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0011_remove_project_members_project_members'), + ('userauth', '0003_rename_tags_user_interest_tags_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='project', + name='members', + field=models.ManyToManyField(blank=True, related_name='member_of_projects', to='userauth.user'), + ), + ] diff --git a/backend/projects/migrations/0013_rename_project_id_project_id.py b/backend/projects/migrations/0013_rename_project_id_project_id.py new file mode 100644 index 0000000..c77e357 --- /dev/null +++ b/backend/projects/migrations/0013_rename_project_id_project_id.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-03-26 04:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0012_alter_project_members'), + ] + + operations = [ + migrations.RenameField( + model_name='project', + old_name='project_id', + new_name='id', + ), + ] diff --git a/backend/projects/models.py b/backend/projects/models.py index 87b97f7..4a3bd66 100644 --- a/backend/projects/models.py +++ b/backend/projects/models.py @@ -4,29 +4,34 @@ import uuid # PROJECTS MODEL class Project(models.Model): - project_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - group = models.CharField(max_length=255) - match_percentage = models.FloatField() - title = models.CharField(max_length=255) - institution = models.CharField(max_length=255) - description = models.TextField() + # Auto generated + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + + # REQUIRED + title = models.CharField(max_length=255, blank=False, null=False) + institution = models.CharField(max_length=255, blank=False, null=False) + description = models.TextField(blank=False, null=False) + positions = models.JSONField(default=list) + image_url = models.ImageField(upload_to="projects/", blank=False, null=False) + + # Not Required + group = models.CharField(max_length=255, blank=True, null=True) followers_count = models.IntegerField(default=0) likes_count = models.IntegerField(default=0) - positions = models.JSONField(default=list) - image_url = models.ImageField(upload_to="projects/", blank=True, null=True) - images = models.JSONField(default=list) - tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) + match_percentage = models.FloatField(blank=True, null=True) + location = models.JSONField(default=list, blank=True) + images = models.JSONField(default=list, blank=True) + interest_tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) + skill_tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) full_description = models.CharField(max_length=1000, blank=True, null=True) email = models.EmailField(unique=True, blank=True, null=True) other_contact = models.CharField(max_length=225, blank=True, null=True) - #discussion = ArrayField(models.CharField(max_length=540), blank=True, null=True) updates = ArrayField(models.CharField(max_length=540), blank=True, null=True) wanted_description = models.CharField(max_length=540, blank=True, null=True) - members = models.ForeignKey( + + members = models.ManyToManyField( 'userauth.User', - on_delete=models.CASCADE, related_name='member_of_projects', - null=True, blank=True ) @@ -38,6 +43,8 @@ class Project(models.Model): blank=True ) + #discussion = ArrayField(models.CharField(max_length=540), blank=True, null=True) - for future + def __str__(self): return self.title diff --git a/backend/projects/urls.py b/backend/projects/urls.py index 82e4b3f..f31094d 100644 --- a/backend/projects/urls.py +++ b/backend/projects/urls.py @@ -4,7 +4,7 @@ urlpatterns = [ path('', get_projects, name='get_projects'), # Fetch all projects path('create/', ProjectCRUDView.as_view(), name='project-create'), # Create project - path('/', ProjectCRUDView.as_view(), name='project-detail'), # Read, Update, Delete project by ID + path('/', ProjectCRUDView.as_view(), name='project-detail'), # Read, Update, Delete project by ID path('like/', toggle_like, name='toggle_like'), path('follow/', toggle_follow, name='toggle_follow') ] diff --git a/backend/userauth/migrations/0003_rename_tags_user_interest_tags_and_more.py b/backend/userauth/migrations/0003_rename_tags_user_interest_tags_and_more.py new file mode 100644 index 0000000..75dc002 --- /dev/null +++ b/backend/userauth/migrations/0003_rename_tags_user_interest_tags_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 5.1.7 on 2025-03-26 04:24 + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('userauth', '0002_user_owned_user_projects_alter_user_email'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='tags', + new_name='interest_tags', + ), + migrations.RenameField( + model_name='user', + old_name='position', + new_name='location_preference', + ), + migrations.AddField( + model_name='user', + name='positions', + field=models.JSONField(default=list), + ), + migrations.AddField( + model_name='user', + name='skill_tags', + field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=225), blank=True, null=True, size=None), + ), + ] diff --git a/backend/userauth/migrations/0004_remove_user_owned_remove_user_projects_user_owned_and_more.py b/backend/userauth/migrations/0004_remove_user_owned_remove_user_projects_user_owned_and_more.py new file mode 100644 index 0000000..e53d9c7 --- /dev/null +++ b/backend/userauth/migrations/0004_remove_user_owned_remove_user_projects_user_owned_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 5.1.7 on 2025-03-26 04:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0012_alter_project_members'), + ('userauth', '0003_rename_tags_user_interest_tags_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='user', + name='owned', + ), + migrations.RemoveField( + model_name='user', + name='projects', + ), + migrations.AddField( + model_name='user', + name='owned', + field=models.ManyToManyField(blank=True, related_name='owners', to='projects.project'), + ), + migrations.AddField( + model_name='user', + name='projects', + field=models.ManyToManyField(blank=True, related_name='contributors', to='projects.project'), + ), + ] diff --git a/backend/userauth/models.py b/backend/userauth/models.py index 54d1f03..979bd35 100644 --- a/backend/userauth/models.py +++ b/backend/userauth/models.py @@ -8,21 +8,19 @@ class User(models.Model): institution = models.CharField(max_length=255, blank=True, null=True) followers = models.IntegerField(default=0) likes = models.IntegerField(default=0) - position = models.JSONField(default=list) - tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) - - projects = models.ForeignKey( + positions = models.JSONField(default=list) + interest_tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) + skill_tags = ArrayField(models.CharField(max_length=225), blank=True, null=True) + location_preference = models.JSONField(default=list) + + projects = models.ManyToManyField( 'projects.Project', - on_delete=models.CASCADE, - related_name='contributors', # good practice to add related_name - null=True, # add null=True if this can be blank + related_name='contributors', blank=True ) - owned = models.ForeignKey( + owned = models.ManyToManyField( 'projects.Project', - on_delete=models.CASCADE, related_name='owners', - null=True, blank=True ) From ebaf688d0920bee80b857da07a676ba7162e689c Mon Sep 17 00:00:00 2001 From: Larry La Date: Tue, 25 Mar 2025 21:41:46 -0700 Subject: [PATCH 5/5] chore: fix pipeline dual runs --- .github/workflows/deployment.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 4a14257..bb0e78a 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -33,9 +33,11 @@ jobs: terraform_version: 1.3.0 - name: Terraform Init + if: github.event_name == 'pull_request' run: terraform -chdir=infra init - name: Terraform Plan + if: github.event_name == 'pull_request' run: terraform -chdir=infra plan -var="db_username=${{ secrets.DB_USER_PROD }}" -var="db_password=${{ secrets.DB_PASSWORD }}" - name: Terraform Apply (for push to main)