Skip to content
Draft
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
4 changes: 2 additions & 2 deletions forms-flow-data-layer/src/db/formio_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from motor.motor_asyncio import AsyncIOMotorClient

from src.config.envs import ENVS
from src.models.formio import FormModel, SubmissionsModel # Import your MongoDB models
from src.models.formio import FormModel, SubmissionModel # Import your MongoDB models
Copy link
Author

Choose a reason for hiding this comment

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

Updated model name to maintain a consistent naming convention.

from src.utils import get_logger

logger = get_logger(__name__)
Expand All @@ -23,7 +23,7 @@ async def init_formio_db(self):
self.__client = AsyncIOMotorClient(ENVS.FORMIO_MONGO_DB_URI)
self.formio_db = self.__client[ENVS.FORMIO_DB_NAME]
await init_beanie(
database=self.formio_db, document_models=[FormModel, SubmissionsModel]
database=self.formio_db, document_models=[FormModel, SubmissionModel]
)

def get_db(self):
Expand Down
8 changes: 4 additions & 4 deletions forms-flow-data-layer/src/graphql/resolvers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import strawberry

from src.graphql.resolvers.submission_resolvers import (
QuerySubmissionsResolver,
)
from src.graphql.resolvers.form_resolvers import QueryFormsResolver
from src.graphql.resolvers.metric_resolvers import QueryMetricsResolver
from src.graphql.resolvers.submission_resolvers import QuerySubmissionsResolver


@strawberry.type
class Query(QuerySubmissionsResolver): # Inherit from query classes
class Query(QuerySubmissionsResolver, QueryMetricsResolver, QueryFormsResolver): # Inherit from query classes
pass
95 changes: 95 additions & 0 deletions forms-flow-data-layer/src/graphql/resolvers/form_resolvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from typing import Optional

import strawberry

from src.graphql.schema import FormSchema, PaginationWindow
from src.graphql.service import FormService
from src.middlewares.auth import auth


@strawberry.type
class QueryFormsResolver:
@strawberry.field(extensions=[auth.auth_required()])
async def get_forms(
self,
info: strawberry.Info,
limit: int = 100,
page_no: int = 1,
order_by: str = 'created',
type: Optional[str] = None,
created_by: Optional[str] = None,
form_name: Optional[str] = None,
status: Optional[str] = None,
parent_form_id: Optional[str] = None,
from_date: Optional[str] = None,
to_date: Optional[str] = None
) -> PaginationWindow[FormSchema]:
"""
GraphQL resolver for querying forms.

Args:
info (strawberry.Info): GraphQL context information
limit (int): Number of items to return (default: 100)
page_no (int): Pagination number (default: 1)
order_by (str): Filter to sort forms by (default: 'created')
type (Optional[str]): Filter on form type
created_by (Optional[str]): Filter on user who created the form
form_name (Optional[str]): Filter on form name
status (Optional[str]): Filter on form status
parent_form_id (Optional[str]): Filter on form parent id
from_date (Optional[str]): Filter from form date
to_date (Optional[str]): Filter to form date
Returns:
Paginated list of Form objects containing combined PostgreSQL and MongoDB data
"""
# Create filters dict. Filters that share names with PostgreSQL or MongoDB column names
# will be applied automatically. Other filters will require additional handling.
filters = {}
filters["order_by"] = order_by
if type:
filters["type"] = type
if created_by:
filters["created_by"] = created_by
if form_name:
filters["form_name"] = form_name
if status:
filters["status"] = status
if parent_form_id:
filters["parent_form_id"] = parent_form_id
if from_date:
filters["from_date"] = from_date
if to_date:
filters["to_date"] = to_date

# Convert page_no to offset
offset = (page_no - 1) * limit

forms = await FormService.get_forms(
user_context=info.context.get("user"),
limit=limit,
offset=offset,
filters=filters
)
return forms


@strawberry.field(extensions=[auth.auth_required()])
async def get_form(
self,
info: strawberry.Info,
form_id: str,
) -> Optional[FormSchema]:
"""
GraphQL resolver for querying form.

Args:
info (strawberry.Info): GraphQL context information
form_id (str): ID of the form
Returns:
Form object containing combined PostgreSQL and MongoDB data
"""
form = await FormService.get_form(
user_context=info.context.get("user"),
form_id=form_id,
)
return form
89 changes: 89 additions & 0 deletions forms-flow-data-layer/src/graphql/resolvers/metric_resolvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from typing import List, Optional

import strawberry

from src.graphql.schema import MetricSchema
from src.graphql.service import MetricService
from src.middlewares.auth import auth


@strawberry.type
class QueryMetricsResolver:
@strawberry.field(extensions=[auth.auth_required()])
async def get_metrics_submission_status(
self,
info: strawberry.Info,
form_id: str,
order_by: str = 'created',
from_date: Optional[str] = None,
to_date: Optional[str] = None,
) -> List[MetricSchema]:
"""
GraphQL resolver for querying submission status metrics.

Args:
info (strawberry.Info): GraphQL context information
form_id (str): ID of the form
order_by (str): Filter to sort submissions by (default: 'created')
from_date (Optional[str]): Filter from submission date
to_date (Optional[str]): Filter to submission date
Returns:
List of Metric objects
"""
# Create filters dict. Filters that share names with PostgreSQL or MongoDB column names
# will be applied automatically. Other filters will require additional handling.
filters = {}
filters["order_by"] = order_by
if form_id:
filters["latest_form_id"] = form_id
if from_date:
filters["from_date"] = from_date
if to_date:
filters["to_date"] = to_date

metrics = await MetricService.get_submission_metrics(
user_context=info.context.get("user"),
metric='application_status',
filters=filters
)
return metrics


@strawberry.field(extensions=[auth.auth_required()])
async def get_metrics_submission_created_by(
self,
info: strawberry.Info,
form_id: str,
order_by: str = 'created',
from_date: Optional[str] = None,
to_date: Optional[str] = None,
) -> List[MetricSchema]:
"""
GraphQL resolver for querying submission created by metrics.

Args:
info (strawberry.Info): GraphQL context information
form_id (str): ID of the form
order_by (str): Filter to sort submissions by (default: 'created')
from_date (Optional[str]): Filter from submission date
to_date (Optional[str]): Filter to submission date
Returns:
List of Metric objects
"""
# Create filters dict. Filters that share names with PostgreSQL or MongoDB column names
# will be applied automatically. Other filters will require additional handling.
filters = {}
filters["order_by"] = order_by
if form_id:
filters["latest_form_id"] = form_id
if from_date:
filters["from_date"] = from_date
if to_date:
filters["to_date"] = to_date

metrics = await MetricService.get_submission_metrics(
user_context=info.context.get("user"),
metric='created_by',
filters=filters
)
return metrics
4 changes: 4 additions & 0 deletions forms-flow-data-layer/src/graphql/schema/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
from src.graphql.schema.form_schema import FormSchema
from src.graphql.schema.metric_schema import MetricSchema
from src.graphql.schema.submission_schema import (
PaginatedSubmissionResponse,
SubmissionDetailsWithSubmissionData,
SubmissionSchema,
)
from src.middlewares.pagination import PaginationWindow

__all__ = [
"FormSchema",
"MetricSchema",
"SubmissionSchema",
"SubmissionDetailsWithSubmissionData",
"PaginatedSubmissionResponse",
"PaginationWindow",
]
57 changes: 52 additions & 5 deletions forms-flow-data-layer/src/graphql/schema/form_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

from src.middlewares.role_check import RoleCheck

# currently this file is not used in the codebase, but it is kept for future use


@strawberry.type
class FormSchema:
Expand All @@ -14,13 +12,62 @@ class FormSchema:
This is the external representation of your database model
"""

# FormIO populated fields
id: str
name: Optional[str] = strawberry.field(
extensions=[RoleCheck(["admin"])]
) # Add this line
)
title: str
path: str
type: str
display: Optional[str] = None
created_at: Optional[str] = None
updated_at: Optional[str] = None
parent_form_id: Optional[str] = None
created: Optional[str] = None
modified: Optional[str] = None

# WebAPI populated fields
created_by: str
modified_by: str
status: str
version: int

# BPM populated fields
# None

# Calculated fields
total_submissions: int

@staticmethod
def from_result(result: dict):
data = {}

# Map FormIO Data
if formio:= result.get("formio"):
data.update({
"id": formio.id,
"title": formio.title,
"name": formio.name,
"path": formio.path,
"type": formio.type,
"display": formio.display,
"parent_form_id": formio.parentFormId,
"created": (formio.created.isoformat() if formio.created else None),
"modified": (formio.modified.isoformat() if formio.modified else None),
})

# Map WebAPI data
if webapi := result.get("webapi"):
data.update({
"created_by": webapi.created_by,
"modified_by": webapi.modified_by,
"status": webapi.status,
"version": webapi.version,
})

# Map Calculated data
if calculated := result.get("calculated"):
data.update({
"total_submissions": calculated["total_submissions"]
})

return FormSchema(**data)
12 changes: 12 additions & 0 deletions forms-flow-data-layer/src/graphql/schema/metric_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import strawberry


@strawberry.type
class MetricSchema:
"""
GraphQL type representing a Metric
This is the external representation of your database model
"""

metric: str
count: int
3 changes: 2 additions & 1 deletion forms-flow-data-layer/src/graphql/service/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from src.graphql.service.form_service import FormService
from src.graphql.service.metric_service import MetricService
from src.graphql.service.submission_service import SubmissionService

__all__ = ["FormService", "SubmissionService"]
__all__ = ["FormService", "MetricService", "SubmissionService"]
Loading