From bbcc893ddf4a148da900a00f1ced8509321f0cd1 Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Mon, 1 Jul 2024 11:37:30 +0100 Subject: [PATCH 1/3] ci(FCL-176): Make pre-commit-hooks consistent across repos Pre-commit gives us a set of high-level hooks which rapidly sense-check aspects of the repository. This commit adds new ones for preventing the addition of large files, checking for filename casing conflicts, preventing committing of files with open merge conflicts, checking XML validity, preventing the addition of submodules, warning when files have mixed line endings, and accidentally committing to `main`. It also reorders this list for clarity. --- .pre-commit-config.yaml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62ab37b8c..5f661660b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,20 @@ -exclude: "^docs/|/migrations/" -default_install_hook_types: [pre-commit, pre-push] +exclude: "/migrations/" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: - - id: trailing-whitespace - - id: end-of-file-fixer + - id: check-added-large-files + - id: check-case-conflict + - id: check-json + - id: check-merge-conflict + - id: check-xml - id: check-yaml + - id: end-of-file-fixer + - id: forbid-submodules + - id: mixed-line-ending + - id: no-commit-to-branch + - id: trailing-whitespace - repo: https://github.com/Riverside-Healthcare/djLint rev: v1.34.1 @@ -39,9 +46,3 @@ repos: hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - -# sets up .pre-commit-ci.yaml to ensure pre-commit dependencies stay up to date -ci: - autoupdate_schedule: weekly - skip: [] - submodules: false From 84662ecbc0f5b9c7c69f2da90effcb03c811cb14 Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Mon, 1 Jul 2024 14:29:33 +0100 Subject: [PATCH 2/3] ci(FCL-176): swap from black/isort to ruff for code formatting --- .pre-commit-config.yaml | 14 +++++++------- config/settings/base.py | 3 +-- config/settings/production.py | 3 +-- ds_caselaw_editor_ui/__init__.py | 5 +---- .../commands/reparse_next_in_reparse_queue.py | 1 + judgments/tests/factories.py | 4 +--- judgments/tests/test_document_history.py | 15 +++------------ judgments/tests/test_judgments.py | 10 ++-------- judgments/tests/test_metadata_panel.py | 5 +---- judgments/tests/test_stats.py | 5 +---- judgments/tests/test_unlock.py | 4 +--- judgments/tests/utils/test_utils.py | 5 +---- judgments/utils/__init__.py | 10 ++-------- judgments/utils/link_generators.py | 4 +--- judgments/utils/view_helpers.py | 4 +--- judgments/views/judgment_hold.py | 6 +----- judgments/views/judgment_publish.py | 6 +----- judgments/views/reports.py | 12 +++--------- pyproject.toml | 14 +++++--------- setup.cfg | 19 ------------------- 20 files changed, 35 insertions(+), 114 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f661660b..657145980 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,6 +16,13 @@ repos: - id: no-commit-to-branch - id: trailing-whitespace + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.0 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + - repo: https://github.com/Riverside-Healthcare/djLint rev: v1.34.1 hooks: @@ -39,10 +46,3 @@ repos: hooks: - id: prettier types_or: [scss, yaml, markdown, javascript, xml] - - - repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.5.0 - hooks: - - id: ruff - args: [--fix, --exit-non-zero-on-fix] diff --git a/config/settings/base.py b/config/settings/base.py index 7dee94b0b..d57c623f8 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -254,8 +254,7 @@ "disable_existing_loggers": False, "formatters": { "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s", + "format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s", }, }, "handlers": { diff --git a/config/settings/production.py b/config/settings/production.py index d45abe278..3f0cad10b 100644 --- a/config/settings/production.py +++ b/config/settings/production.py @@ -110,8 +110,7 @@ "filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}}, "formatters": { "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s", + "format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s", }, }, "handlers": { diff --git a/ds_caselaw_editor_ui/__init__.py b/ds_caselaw_editor_ui/__init__.py index 3fff62c9f..15a15abda 100644 --- a/ds_caselaw_editor_ui/__init__.py +++ b/ds_caselaw_editor_ui/__init__.py @@ -1,7 +1,4 @@ __version__ = "0.1.0" __version_info__ = tuple( - [ - int(num) if num.isdigit() else num - for num in __version__.replace("-", ".", 1).split(".") - ], + [int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".")], ) diff --git a/judgments/management/commands/reparse_next_in_reparse_queue.py b/judgments/management/commands/reparse_next_in_reparse_queue.py index 251612eb5..7f268bac1 100644 --- a/judgments/management/commands/reparse_next_in_reparse_queue.py +++ b/judgments/management/commands/reparse_next_in_reparse_queue.py @@ -9,6 +9,7 @@ NUMBER_TO_PARSE = 1 MAX_DOCUMENTS_TO_TRY = 200 + class Command(BaseCommand): help = "Sends the next document in the reparse queue to be reparsed" diff --git a/judgments/tests/factories.py b/judgments/tests/factories.py index f1b15c79c..760d01de1 100644 --- a/judgments/tests/factories.py +++ b/judgments/tests/factories.py @@ -55,9 +55,7 @@ def build(cls, **kwargs) -> DocumentClass: if "html" in kwargs: document_mock.return_value.content_as_html.return_value = kwargs.pop("html") else: - document_mock.return_value.content_as_html.return_value = ( - "

This is a judgment.

" - ) + document_mock.return_value.content_as_html.return_value = "

This is a judgment.

" for map_to, map_from in cls.PARAMS_MAP.items(): if map_from[0] in kwargs: diff --git a/judgments/tests/test_document_history.py b/judgments/tests/test_document_history.py index c4d0c49d4..f5ce3457e 100644 --- a/judgments/tests/test_document_history.py +++ b/judgments/tests/test_document_history.py @@ -30,10 +30,7 @@ def test_document_history_view(self, document_type, document_exists, mock_docume self.client.force_login(User.objects.get_or_create(username="testuser")[0]) - assert ( - reverse("document-history", kwargs={"document_uri": document.uri}) - == "/edtest/4321/123/history" - ) + assert reverse("document-history", kwargs={"document_uri": document.uri}) == "/edtest/4321/123/history" response = self.client.get( reverse("document-history", kwargs={"document_uri": document.uri}), @@ -405,10 +402,7 @@ def test_structured_history_with_legacy( self.sign_in_developer_user() - assert ( - reverse("document-history", kwargs={"document_uri": document.uri}) - == "/test/4321/123/history" - ) + assert reverse("document-history", kwargs={"document_uri": document.uri}) == "/test/4321/123/history" response = self.client.get( reverse("document-history", kwargs={"document_uri": document.uri}), @@ -503,10 +497,7 @@ def test_structured_history( self.sign_in_developer_user() - assert ( - reverse("document-history", kwargs={"document_uri": document.uri}) - == "/test/4321/123/history" - ) + assert reverse("document-history", kwargs={"document_uri": document.uri}) == "/test/4321/123/history" response = self.client.get( reverse("document-history", kwargs={"document_uri": document.uri}), diff --git a/judgments/tests/test_judgments.py b/judgments/tests/test_judgments.py index 0e7d924f3..b1eb6c5bb 100644 --- a/judgments/tests/test_judgments.py +++ b/judgments/tests/test_judgments.py @@ -25,10 +25,7 @@ def test_judgment_html_view(self, document_type, document_exists, mock_judgment) self.client.force_login(User.objects.get_or_create(username="testuser")[0]) - assert ( - reverse("full-text-html", kwargs={"document_uri": judgment.uri}) - == "/hvtest/4321/123" - ) + assert reverse("full-text-html", kwargs={"document_uri": judgment.uri}) == "/hvtest/4321/123" response = self.client.get( reverse("full-text-html", kwargs={"document_uri": judgment.uri}), @@ -118,10 +115,7 @@ def test_judgment_pdf_view_no_pdf_response( self.client.force_login(User.objects.get_or_create(username="testuser")[0]) response = self.client.get("/test/1234/pdf") decoded_response = response.content.decode("utf-8") - assert ( - "Document "JUDGMENT v JUDGEMENT" does not have a PDF." - in decoded_response - ) + assert "Document "JUDGMENT v JUDGEMENT" does not have a PDF." in decoded_response assert response.status_code == 404 def test_judgment_xml_view_redirect(self): diff --git a/judgments/tests/test_metadata_panel.py b/judgments/tests/test_metadata_panel.py index 8bb37823d..49a7537b6 100644 --- a/judgments/tests/test_metadata_panel.py +++ b/judgments/tests/test_metadata_panel.py @@ -28,8 +28,5 @@ def test_metadata_panel(self, document_type, document_exists, mock_judgment): reverse("full-text-html", kwargs={"document_uri": judgment.uri}), ) - assert ( - b'' - in response.content - ) + assert b'' in response.content assert response.status_code == 200 diff --git a/judgments/tests/test_stats.py b/judgments/tests/test_stats.py index 3996a50da..822a86a16 100644 --- a/judgments/tests/test_stats.py +++ b/judgments/tests/test_stats.py @@ -29,7 +29,4 @@ def test_combined_csv_download(self, mock_api_client): decoded_response = response.content.decode("utf-8") assert response.status_code == 200 - assert ( - decoded_response - == "Column 1,Column 2,Column 3,Column 4\r\nValue 1,Value 2,,7\r\n" - ) + assert decoded_response == "Column 1,Column 2,Column 3,Column 4\r\nValue 1,Value 2,,7\r\n" diff --git a/judgments/tests/test_unlock.py b/judgments/tests/test_unlock.py index c2b12a997..944ed1298 100644 --- a/judgments/tests/test_unlock.py +++ b/judgments/tests/test_unlock.py @@ -14,9 +14,7 @@ def test_break_lock_confirm_page(): response = client.get("/unlock?judgment_uri=my_uri") decoded_response = response.content.decode("utf-8") - assert ( - '' in decoded_response - ) + assert '' in decoded_response assert response.status_code == 200 diff --git a/judgments/tests/utils/test_utils.py b/judgments/tests/utils/test_utils.py index db9484213..d7d846dd8 100644 --- a/judgments/tests/utils/test_utils.py +++ b/judgments/tests/utils/test_utils.py @@ -182,10 +182,7 @@ def test_when_referrer_is_relative(self, request): def test_when_referrer_is_absolute_and_local(self, request): request.META = {"HTTP_REFERER": "https://www.example.com/foo/bar"} request.get_host.return_value = "www.example.com" - assert ( - ensure_local_referer_url(request, "/default") - == "https://www.example.com/foo/bar" - ) + assert ensure_local_referer_url(request, "/default") == "https://www.example.com/foo/bar" @patch("django.http.request.HttpRequest") def test_when_referrer_is_absolute_and_remote(self, request): diff --git a/judgments/utils/__init__.py b/judgments/utils/__init__.py index a4b2c062d..64f01a5a3 100644 --- a/judgments/utils/__init__.py +++ b/judgments/utils/__init__.py @@ -96,9 +96,7 @@ def update_document_uri(old_uri, new_citation): copy_assets(old_uri, new_uri) api_client.set_judgment_this_uri(new_uri) except MarklogicAPIError as e: - msg = ( - f"Failure when attempting to copy document from {old_uri} to {new_uri}: {e}" - ) + msg = f"Failure when attempting to copy document from {old_uri} to {new_uri}: {e}" raise MoveJudgmentError( msg, ) from e @@ -178,11 +176,7 @@ def editors_dict(): def get_linked_document_uri(document: Document) -> str | None: related_uri = _build_related_document_uri(document) - return ( - related_uri - if api_client.document_exists(DocumentURIString(related_uri)) - else None - ) + return related_uri if api_client.document_exists(DocumentURIString(related_uri)) else None def _build_related_document_uri(document: Document) -> str: diff --git a/judgments/utils/link_generators.py b/judgments/utils/link_generators.py index 708b291cc..118a69036 100644 --- a/judgments/utils/link_generators.py +++ b/judgments/utils/link_generators.py @@ -31,9 +31,7 @@ def build_confirmation_email_link( document: Document, signature: str | None = None, ) -> str: - subject_string = ( - f"Notification of publication [TDR ref: {document.consignment_reference}]" - ) + subject_string = f"Notification of publication [TDR ref: {document.consignment_reference}]" email_context = { "judgment_name": document.name, diff --git a/judgments/utils/view_helpers.py b/judgments/utils/view_helpers.py index 37b97bf56..4da903455 100644 --- a/judgments/utils/view_helpers.py +++ b/judgments/utils/view_helpers.py @@ -44,9 +44,7 @@ def get_search_parameters( ): query = params.get("query") page = int(params.get("page", default_page)) - order = ( - params.get("order") if params.get("order") in ALLOWED_ORDERS else default_order - ) + order = params.get("order") if params.get("order") in ALLOWED_ORDERS else default_order return { "query": query, "page": page, diff --git a/judgments/views/judgment_hold.py b/judgments/views/judgment_hold.py index e04170a4a..3f94054ee 100644 --- a/judgments/views/judgment_hold.py +++ b/judgments/views/judgment_hold.py @@ -24,11 +24,7 @@ def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["email_issue_link"] = build_raise_issue_email_link( document=context["document"], - signature=( - self.request.user.get_full_name() - if self.request.user.is_authenticated - else None - ), + signature=(self.request.user.get_full_name() if self.request.user.is_authenticated else None), ) return context diff --git a/judgments/views/judgment_publish.py b/judgments/views/judgment_publish.py index ded11e892..b764508d0 100644 --- a/judgments/views/judgment_publish.py +++ b/judgments/views/judgment_publish.py @@ -24,11 +24,7 @@ def get_context_data(self, **kwargs): context["email_confirmation_link"] = build_confirmation_email_link( document=context["document"], - signature=( - self.request.user.get_full_name() - if self.request.user.is_authenticated - else None - ), + signature=(self.request.user.get_full_name() if self.request.user.is_authenticated else None), ) return context diff --git a/judgments/views/reports.py b/judgments/views/reports.py index 0233e93bf..a4c093538 100644 --- a/judgments/views/reports.py +++ b/judgments/views/reports.py @@ -37,9 +37,7 @@ def get_context_data(self, **kwargs): target_parser_version = api_client.get_highest_parser_version() context["page_title"] = "Documents awaiting parsing" - context["target_parser_version"] = ( - f"{target_parser_version[0]}.{target_parser_version[1]}" - ) + context["target_parser_version"] = f"{target_parser_version[0]}.{target_parser_version[1]}" context["documents"] = get_rows_from_result( api_client.get_pending_parse_for_version( @@ -60,12 +58,8 @@ def get_context_data(self, **kwargs): target_parser_version = api_client.get_highest_parser_version() context["page_title"] = "Documents awaiting enrichment" - context["target_enrichment_version"] = ( - f"{target_enrichment_version[0]}.{target_enrichment_version[1]}" - ) - context["target_parser_version"] = ( - f"{target_parser_version[0]}.{target_parser_version[1]}" - ) + context["target_enrichment_version"] = f"{target_enrichment_version[0]}.{target_enrichment_version[1]}" + context["target_parser_version"] = f"{target_parser_version[0]}.{target_parser_version[1]}" context["documents"] = get_rows_from_result( api_client.get_pending_enrichment_for_version( diff --git a/pyproject.toml b/pyproject.toml index d8ff55420..58f020041 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ indent=2 custom_blocks="flag" [tool.ruff] +line-length = 120 [tool.ruff.lint] ignore = ["E501", "G004", "PLR2004", "RUF005", "RUF012", "UP040"] # long lines, fstrings in logs, magic values, consider not concat, mutable classbits, type instead of TypeAlias @@ -17,8 +18,8 @@ extend-select = ["W", "B", "Q", "C90", "I", "UP", "YTT", "ASYNC", "S", "BLE", "A unfixable = ["ERA"] # things skipped: -# N: naming, possibly good -# D: docstrings missing throughout +# N: naming, possibly good +# D: docstrings missing throughout # ANN: annotations missing throughout # FBT: not convinced boolean trap worth auto-banning. # CPY: copyright at top of each file @@ -40,10 +41,5 @@ unfixable = ["ERA"] "T201"] # OK to have prints here "merge_production_dotenvs_in_dotenv.py" = ["S101"] # TODO: fix this "*.*" = ["DTZ001", "DTZ007", "INP001", "PTH123", "PTH110"] # TODO: fix -"judgments/*" = ["FIX002"] # TODOs, should fix -"conftest.py" = ["PT004"] # not even sure what this code is doing. - -[tool.ruff.lint.isort] -known-first-party = ["ds-caselaw-editor-ui", "config"] - -[tool.ruff.lint.pycodestyle] +"judgments/*" = ["FIX002"] # TODOs, should fix +"conftest.py" = ["PT004"] # not even sure what this code is doing. diff --git a/setup.cfg b/setup.cfg index 66a11f577..4d46dd209 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,22 +1,3 @@ -[flake8] -max-line-length = 120 -exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv - -[pycodestyle] -max-line-length = 120 -exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv - -[isort] -line_length = 88 -known_first_party = ds-caselaw-editor-ui,config -multi_line_output = 3 -default_section = THIRDPARTY -skip = venv/ -skip_glob = **/migrations/*.py -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true - [mypy] check_untyped_defs = True ignore_missing_imports = True From e4388618df940f3b2e06076852b14c170c0f9b53 Mon Sep 17 00:00:00 2001 From: Nick Jackson Date: Tue, 2 Jul 2024 12:40:07 +0100 Subject: [PATCH 3/3] ci(FCL-176): update prettier behaviour for cross-repo consistency --- .pre-commit-config.yaml | 4 ++-- auth0/attack-protection/brute-force-protection.json | 5 +---- auth0/attack-protection/suspicious-ip-throttling.json | 5 +---- auth0/clients/auth0-deploy-cli-extension.json | 4 +--- auth0/clients/production.json | 4 +--- auth0/clients/staging.json | 4 ++-- auth0/config.example.json | 10 ++++------ .../Username-Password-Authentication/database.json | 9 ++------- auth0/tenant.json | 4 +--- 9 files changed, 15 insertions(+), 34 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 657145980..ef8b0b1dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,7 +42,7 @@ repos: language: python - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.1.0 + rev: v4.0.0-alpha.8 hooks: - id: prettier - types_or: [scss, yaml, markdown, javascript, xml] + types_or: [yaml, json, xml, markdown, scss, javascript] diff --git a/auth0/attack-protection/brute-force-protection.json b/auth0/attack-protection/brute-force-protection.json index 22bbe60e9..20510787b 100644 --- a/auth0/attack-protection/brute-force-protection.json +++ b/auth0/attack-protection/brute-force-protection.json @@ -1,9 +1,6 @@ { "enabled": true, - "shields": [ - "block", - "user_notification" - ], + "shields": ["block", "user_notification"], "mode": "count_per_identifier_and_ip", "allowlist": [], "max_attempts": 10 diff --git a/auth0/attack-protection/suspicious-ip-throttling.json b/auth0/attack-protection/suspicious-ip-throttling.json index 6717df212..85b39808a 100644 --- a/auth0/attack-protection/suspicious-ip-throttling.json +++ b/auth0/attack-protection/suspicious-ip-throttling.json @@ -1,9 +1,6 @@ { "enabled": true, - "shields": [ - "admin_notification", - "block" - ], + "shields": ["admin_notification", "block"], "allowlist": [], "stage": { "pre-login": { diff --git a/auth0/clients/auth0-deploy-cli-extension.json b/auth0/clients/auth0-deploy-cli-extension.json index 31940ae53..4e5ebd103 100644 --- a/auth0/clients/auth0-deploy-cli-extension.json +++ b/auth0/clients/auth0-deploy-cli-extension.json @@ -21,8 +21,6 @@ }, "token_endpoint_auth_method": "client_secret_post", "app_type": "non_interactive", - "grant_types": [ - "client_credentials" - ], + "grant_types": ["client_credentials"], "custom_login_page_on": true } diff --git a/auth0/clients/production.json b/auth0/clients/production.json index 0119209da..e2f3d98c7 100644 --- a/auth0/clients/production.json +++ b/auth0/clients/production.json @@ -31,7 +31,5 @@ "client_credentials" ], "custom_login_page_on": true, - "web_origins": [ - "https://editor.caselaw.nationalarchives.gov.uk" - ] + "web_origins": ["https://editor.caselaw.nationalarchives.gov.uk"] } diff --git a/auth0/clients/staging.json b/auth0/clients/staging.json index 96d9b5318..0600f4f9b 100644 --- a/auth0/clients/staging.json +++ b/auth0/clients/staging.json @@ -33,6 +33,6 @@ "custom_login_page_on": true, "web_origins": [ "https://editor.staging.caselaw.nationalarchives.gov.uk", - "https://editor.staging.caselaw-stg.dalmatian.dxw.net" - ] + "https://editor.staging.caselaw-stg.dalmatian.dxw.net" + ] } diff --git a/auth0/config.example.json b/auth0/config.example.json index fd01a2d22..a828ec373 100644 --- a/auth0/config.example.json +++ b/auth0/config.example.json @@ -2,15 +2,13 @@ "AUTH0_DOMAIN": "tna-caselaw-editorial-team.eu.auth0.com", "AUTH0_CLIENT_ID": "", "AUTH0_CLIENT_SECRET": "", - "AUTH0_KEYWORD_REPLACE_MAPPINGS": { - }, + "AUTH0_KEYWORD_REPLACE_MAPPINGS": {}, "AUTH0_ALLOW_DELETE": false, - "AUTH0_EXCLUDED_RULES": [ - ], + "AUTH0_EXCLUDED_RULES": [], "INCLUDED_PROPS": { - "clients": [ ] + "clients": [] }, "EXCLUDED_PROPS": { - "connections": [ "options.client_secret" ] + "connections": ["options.client_secret"] } } diff --git a/auth0/database-connections/Username-Password-Authentication/database.json b/auth0/database-connections/Username-Password-Authentication/database.json index c23e1240e..474bd43f9 100644 --- a/auth0/database-connections/Username-Password-Authentication/database.json +++ b/auth0/database-connections/Username-Password-Authentication/database.json @@ -12,11 +12,6 @@ "strategy": "auth0", "name": "Username-Password-Authentication", "is_domain_connection": false, - "realms": [ - "Username-Password-Authentication" - ], - "enabled_clients": [ - "staging", - "production" - ] + "realms": ["Username-Password-Authentication"], + "enabled_clients": ["staging", "production"] } diff --git a/auth0/tenant.json b/auth0/tenant.json index 27524e769..3728f1390 100644 --- a/auth0/tenant.json +++ b/auth0/tenant.json @@ -1,8 +1,6 @@ { "friendly_name": "Case Law Editorial Team", - "enabled_locales": [ - "en" - ], + "enabled_locales": ["en"], "flags": { "universal_login": true, "revoke_refresh_token_grant": false,