Skip to content

BCAP Messaging backend - #1611

Merged
bferguso merged 8 commits into
release/2.0.xfrom
ts/feat/1593_bcap_messaging_backend
Jul 10, 2026
Merged

BCAP Messaging backend#1611
bferguso merged 8 commits into
release/2.0.xfrom
ts/feat/1593_bcap_messaging_backend

Conversation

@seeker25

@seeker25 seeker25 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

bcgov/arches-zod-validation#3 <-- ideally needs to get merged as well

I didn't try the dashboard counts beyond just loading them - I think they are covered in unit tests though. We should have a function that will work for counts on a process requirement basis.

Comment on lines +46 to +62
CONTRIBUTOR_TYPES = [
# (item id, prefLabel value id, label, sortorder, concept uri)
(
"8c4e2933-a97a-5f47-89e7-78d1d8aaad81",
"c0b10d00-fbfa-58c3-ba46-3dc39d61a87e",
"Individual",
0,
"http://bcap/bcap8c4e2933-a97a-5f47-89e7-78d1d8aaad81",
),
(
"fd2053d3-c010-519a-97e5-52f3c7b508e2",
"891278e4-5d67-571a-a0c4-414896d36d1c",
"Organization",
1,
"http://bcap/bcapfd2053d3-c010-519a-97e5-52f3c7b508e2",
),
]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to add these - we don't have pkg file that load them in

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added some comments as per Brett's suggestion for this

@seeker25
seeker25 requested review from P-Hansen and bferguso July 9, 2026 19:46
z.iso.date(),
z.iso.datetime({ offset: true, local: true })
]).nullable()
node_value: z.string().regex(/^\d{4}-\d{2}-\d{2}([ T]\d{2}:\d{2}:\d{2}([+-]\d{2}:\d{2}|Z)?)?$/).nullable()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to do this, arches dates aren't saved as ISO - there is a way to override that but it impacts other dates/datetimes

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I try to change how arches saves the date it can impact other dates in the system, so I've opted to just make this a bit more flexible on the frontend

Comment on lines +22 to +31
def register_offset_preserving_date_field():
"""Use the offset-preserving field for date nodes on the REST write path.
Call from AppConfig.ready(): the imports must be deferred until the app
registry is loaded."""
from django.db.models import DateTimeField
from arches_querysets.rest_framework.serializers import TileAliasedDataSerializer

TileAliasedDataSerializer.register_custom_datatype_field(
DateTimeField, OffsetPreservingDateTimeField
)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arches queryset problem I'll create a PR if I have some time

@seeker25 seeker25 changed the title BCAP Messaging backend base commit BCAP Messaging backend Jul 9, 2026

@P-Hansen P-Hansen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@seeker25

Copy link
Copy Markdown
Collaborator Author

we may need a way to get counts not on a dashboard route, but we'll see as you implement

Comment on lines +26 to +45
def submission_context_ids_for_permits(self, permits, requirements_by_permit=None):
"""Map each permit to the resource ids its unread counts span (the permit
and its requirements' submission hosts); pass known requirement ids to
skip a query."""
permit_ids = [str(permit.pk) for permit in permits]
contexts = {pk: {pk} for pk in permit_ids}

if requirements_by_permit is None:
requirements_by_permit = self._requirements.requirement_ids_by_permit(
permit_ids
)
all_requirement_ids = set(chain.from_iterable(requirements_by_permit.values()))
hosts_by_requirement = self._requirements.host_ids_by_requirement(
all_requirement_ids
)
for permit_id, requirement_ids in requirements_by_permit.items():
for requirement_id in requirement_ids:
hosts = hosts_by_requirement.get(requirement_id, ())
contexts[permit_id].update(hosts)
return contexts

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might need this done at the module level as well (groupings of process requirements)

next PR or another PR

Comment thread bcap/schema.py
Comment on lines -31 to -39
def _date_node_value(max_length):
# Accept a bare date or a full datetime; anyOf becomes a zod union.
return {
"nullable": True,
"anyOf": [
{"type": "string", "format": "date"},
{"type": "string", "format": "date-time"},
],
}

@seeker25 seeker25 Jul 10, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this a bit and moved to zod-validation library. It would work for createdon (on the model) but not for message_created_on (inside the json)

Comment on lines +1 to +14
<script setup lang="ts">
import { reactive } from 'vue';
import { z } from 'zod';
import arches from 'arches';
import {
zApiPermitApplicationCreateResponse,
zBcapMessage,
zBcapMessageWritable,
zPaginatedBcapMessageList,
zPaginatedContributorList,
} from '@/bcap/client/zod.gen.ts';
import { formatDateTime, getCsrfToken, getDisplayValue } from '@/bcap/util.ts';
import type { AliasedNodeData } from '@/arches_component_lab/types.ts';

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll need to gun this file when Philip is done with it

Comment on lines +71 to +77
{
id: 'site-visit',
label: 'Site Visit',
subtitle: 'Coming soon',
icon: 'fa fa-location-dot',
disabled: true,
},

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Site visit as requested in the menu / tiles at the end

return False
tile.data[username_node] = username
tile.save()
Resource.objects.get(pk=contributor_id).index()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we were missing this, we may need to do a simple python script to reindex some users =(

Comment on lines +115 to +123
path: arches.urls.plugin('external-permit-workflows/message-demo'),
name: 'messageDemo',
component: () =>
import('@/bcap/apps/Permit/components/MessageDemo.vue'),
meta: {
shouldShowNavigation: true,
requiresAuthentication: true,
},
},

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove, this is temp

Comment thread bcap/util/auth/roles.py
Comment on lines +32 to +39
def is_internal_user(user):
"""True if the user is ministry staff (a superuser or holds an internal
role); everyone else is treated as an external applicant."""
if not getattr(user, "is_authenticated", False):
return False
if getattr(user, "is_superuser", False):
return True
return user.groups.filter(name__in=INTERNAL_ROLES).exists()

@seeker25 seeker25 Jul 10, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think replacing this with granting group access will replace this in the future with Guardian
image

Comment thread pyproject.toml Outdated
@seeker25

seeker25 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator Author

Might need some url clean up next PR

api/bcap_message/<uuid:pk>/
vs
api/bcap_message/<uuid:pk>

If you are using Django or Django REST Framework (DRF), the trailing slash is the strict default. Django uses a setting called APPEND_SLASH = True.

If a client hits api/requirement_submission/<uuid:pk>, Django will automatically return a 301 Moved Permanently redirect to api/requirement_submission/<uuid:pk>/.

@bferguso bferguso left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! This is a great push forward.

If you have time next week lets try to move the queryset patch into the arches-querysets so we don't forget about it and start to drift.

@bferguso
bferguso merged commit b9f7f95 into release/2.0.x Jul 10, 2026
8 of 9 checks passed
@bferguso
bferguso deleted the ts/feat/1593_bcap_messaging_backend branch July 10, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants