Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion deployment/terraform/cdn.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ locals {
path_pattern = "api/v1/production-locations*"
default_ttl = var.api_production_locations_cache_default_ttl
max_ttl = var.api_production_locations_cache_max_ttl
},
{
path_pattern = "api/partner-field-groups/*"
default_ttl = var.api_partner_field_groups_cache_default_ttl
max_ttl = var.api_partner_field_groups_cache_max_ttl
},
{
path_pattern = "api/partner-fields/*"
default_ttl = var.api_partner_fields_cache_default_ttl
max_ttl = var.api_partner_fields_cache_max_ttl
},
{
path_pattern = "api/contributors/"
default_ttl = var.api_contributors_cache_default_ttl
max_ttl = var.api_contributors_cache_max_ttl
},
{
path_pattern = "api/contributor-lists-sorted/*"
default_ttl = var.api_contributor_lists_sorted_cache_default_ttl
max_ttl = var.api_contributor_lists_sorted_cache_max_ttl
},
{
path_pattern = "api/parent-companies/*"
default_ttl = var.api_parent_companies_cache_default_ttl
max_ttl = var.api_parent_companies_cache_max_ttl
}
]
}
Expand Down Expand Up @@ -213,7 +238,7 @@ resource "aws_cloudfront_distribution" "cdn" {

forwarded_values {
query_string = true
headers = [
headers = [
"Host",
"Authorization",
"X-OAR-CLIENT-KEY",
Expand Down
60 changes: 60 additions & 0 deletions deployment/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,66 @@ variable "api_production_locations_cache_max_ttl" {
default = 120
}

variable "api_partner_field_groups_cache_default_ttl" {
description = "Default TTL (seconds) for partner field groups endpoint"
type = number
default = 120
}

variable "api_partner_field_groups_cache_max_ttl" {
description = "Max TTL (seconds) for partner field groups endpoint"
type = number
default = 300
}

variable "api_partner_fields_cache_default_ttl" {
description = "Default TTL (seconds) for partner fields endpoint"
type = number
default = 120
}

variable "api_partner_fields_cache_max_ttl" {
description = "Max TTL (seconds) for partner fields endpoint"
type = number
default = 300
}

variable "api_contributors_cache_default_ttl" {
description = "Default TTL (seconds) for API contributors endpoints"
type = number
default = 120
}

variable "api_contributors_cache_max_ttl" {
description = "Max TTL (seconds) for API contributors endpoints"
type = number
default = 300
}

variable "api_contributor_lists_sorted_cache_default_ttl" {
description = "Default TTL (seconds) for API contributor lists sorted endpoints"
type = number
default = 120
}

variable "api_contributor_lists_sorted_cache_max_ttl" {
description = "Max TTL (seconds) for API contributor lists sorted endpoints"
type = number
default = 300
}

variable "api_parent_companies_cache_default_ttl" {
description = "Default TTL (seconds) for API parent companies endpoints"
type = number
default = 120
}

variable "api_parent_companies_cache_max_ttl" {
description = "Max TTL (seconds) for API parent companies endpoints"
type = number
default = 300
}

variable "vpc_cidr_block" {
default = "10.0.0.0/16"
}
Expand Down
1 change: 1 addition & 0 deletions doc/release/RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
* Previously opened facility pages at `/facilities/:osID` will redirect to `/production-locations/:osID` after page refresh.
* When the feature flag is disabled, accessing `/production-locations/:osID` routes will result in a "Not found" page with no automatic redirection to the legacy `/facilities/:osID` route.
* [OSDEV-2353](https://opensupplyhub.atlassian.net/browse/OSDEV-2353) - Created basic layout components for new Production Location page redesign.
* [OSDEV-2356](https://opensupplyhub.atlassian.net/browse/OSDEV-2356) - Added `GET api/partner-field-groups/` endpoint to retrieve partner field groups with pagination support and CDN caching for the endpoint (and additional endpoints for partner fields and contributors).

### Release instructions
* Ensure that the following commands are included in the `post_deployment` command:
Expand Down
38 changes: 30 additions & 8 deletions src/django/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.utils.translation import gettext as _
from api.models.sector_group import SectorGroup
from api.models.partner_field import PartnerField
from api.models.partner_field_group import PartnerFieldGroup
from api.models.wage_indicator_country_data import WageIndicatorCountryData
from api.models.wage_indicator_link_text_config import (
WageIndicatorLinkTextConfig
Expand Down Expand Up @@ -334,14 +335,34 @@ def clean(self):

class PartnerFieldAdmin(admin.ModelAdmin):
form = PartnerFieldAdminForm
list_display = ('name', 'type', 'label', 'unit', 'active', 'system_field',
'created_at')
search_fields = ('name', 'type', 'label', 'unit', 'source_by')
list_filter = ('active', 'system_field', 'type')
readonly_fields = ('uuid', 'created_at', 'updated_at')
fields = ('name', 'type', 'unit', 'label', 'source_by', 'base_url',
'display_text', 'json_schema', 'active', 'system_field',
'created_at', 'updated_at')
list_display = (
"name",
"type",
"label",
"unit",
"group",
"active",
"system_field",
"created_at",
)
search_fields = ("name", "type", "label", "unit", "source_by")
list_filter = ("active", "system_field", "type", "group")
readonly_fields = ("uuid", "created_at", "updated_at")
fields = (
"name",
"type",
"unit",
"label",
"group",
"source_by",
"base_url",
"display_text",
"json_schema",
"active",
"system_field",
"created_at",
"updated_at",
)

def get_queryset(self, request):
'''
Expand Down Expand Up @@ -432,6 +453,7 @@ class USCountyTigerlineAdmin(admin.ModelAdmin):
admin_site.register(SectorGroup, SectorGroupAdmin)
admin_site.register(models.FacilityDownloadLimit, FacilityDownloadLimitAdmin)
admin_site.register(PartnerField, PartnerFieldAdmin)
admin_site.register(PartnerFieldGroup)
admin_site.register(EmailAddress, EmailAddressAdmin)
admin_site.register(WageIndicatorCountryData, WageIndicatorCountryDataAdmin)
admin_site.register(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Generated by Django 5.2.10 on 2026-02-26 13:28

import django.db.models.deletion
import django_ckeditor_5.fields
import uuid
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("api", "0200_introduce_indexing_of_the_creation_date_of_the_claim_request"),
]

operations = [
migrations.CreateModel(
name="PartnerFieldGroup",
fields=[
(
"uuid",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique identifier for the partner field group.",
primary_key=True,
serialize=False,
),
),
(
"name",
models.CharField(
help_text="The partner field group name.",
max_length=200,
unique=True,
),
),
(
"order",
models.IntegerField(
default=0,
help_text="Order for the partner field group in the UI.",
),
),
(
"icon_file",
models.ImageField(
blank=True,
help_text="Upload an icon image.",
null=True,
upload_to="partner_field_groups/icons/",
),
),
(
"description",
django_ckeditor_5.fields.CKEditor5Field(
blank=True,
help_text="Rich text description of the partner field group.",
null=True,
),
),
(
"helper_text",
django_ckeditor_5.fields.CKEditor5Field(
blank=True,
help_text="Rich text helper text for the partner field group.",
null=True,
),
),
(
"created_at",
models.DateTimeField(auto_now_add=True),
),
(
"updated_at",
models.DateTimeField(auto_now=True),
),
],
options={
"verbose_name_plural": "Partner field groups",
"ordering": ["order"],
},
),
migrations.AddField(
model_name="partnerfield",
name="group",
field=models.ForeignKey(
blank=True,
help_text="The group this partner field belongs to.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="partner_fields",
to="api.partnerfieldgroup",
),
),
]
2 changes: 2 additions & 0 deletions src/django/api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
HistoricalExtendedField
)
from .nonstandard_field import NonstandardField
from .partner_field import PartnerField
from .partner_field_group import PartnerFieldGroup
from .product_type import ProductType
from .production_type import ProductionType
from .request_log import RequestLog
Expand Down
8 changes: 8 additions & 0 deletions src/django/api/models/partner_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ class Meta:
"System fields cannot be deleted and have restricted editing."
),
)
group = models.ForeignKey(
'PartnerFieldGroup',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='partner_fields',
help_text="The group this partner field belongs to.",
)

created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Expand Down
51 changes: 51 additions & 0 deletions src/django/api/models/partner_field_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import uuid
from django.db import models
from django_ckeditor_5.fields import CKEditor5Field


class PartnerFieldGroup(models.Model):
"""
Group for partner fields.
"""

uuid = models.UUIDField(
default=uuid.uuid4,
primary_key=True,
editable=False,
help_text="Unique identifier for the partner field group.",
)
name = models.CharField(
max_length=200,
unique=True,
null=False,
help_text="The partner field group name.",
)
order = models.IntegerField(
default=0,
help_text="Order for the partner field group in the UI.",
)
icon_file = models.ImageField(
upload_to="partner_field_groups/icons/",
blank=True,
null=True,
help_text="Upload an icon image.",
)
description = CKEditor5Field(
blank=True,
null=True,
help_text="Rich text description of the partner field group.",
)
helper_text = CKEditor5Field(
blank=True,
null=True,
help_text="Rich text helper text for the partner field group.",
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

class Meta:
verbose_name_plural = "Partner field groups"
ordering = ["order"]

def __str__(self):
return self.name
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Serializer for partner field groups.
Specifies the fields that are returned by
the GET /api/partner-field-groups/ API endpoint.
"""

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from api.models.partner_field_group import PartnerFieldGroup


class PartnerFieldGroupSerializer(ModelSerializer):
"""
Serializer for the PartnerFieldGroup model.
Serializes the fields and related partner_fields for the API response.
"""

partner_fields = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field="name",
)

class Meta:
"""
Meta class for partner field group serializer.
Specifies the fields that are returned by the API response.
"""

model = PartnerFieldGroup
fields = [
"uuid",
"name",
"order",
"icon_file",
"description",
"helper_text",
"partner_fields",
"created_at",
"updated_at",
]
Loading