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
26 changes: 13 additions & 13 deletions app/models/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import models.entities.Configuration.*
import models.entities.DiseaseHPOs.*
import models.entities.Drug.*
import models.entities.DrugWarning.*
import models.entities.EnhancerToGenes.*
import models.entities.Interactions.*
import models.entities.Intervals.*
import models.entities.Loci.*
import models.entities.MechanismsOfAction.*
import models.entities.MousePhenotypes.*
Expand Down Expand Up @@ -728,14 +728,14 @@ class Backend @Inject() (implicit
dbRetriever.executeQuery[InteractionResources, Query](interactionSourcesQuery.query)
}

def getIntervals(chromosome: String,
start: Int,
end: Int,
pagination: Option[Pagination]
): Future[Intervals] = {
val tableName = getTableWithPrefixOrDefault(defaultOTSettings.clickhouse.intervals.name)
def getEnhancerToGenes(chromosome: String,
start: Int,
end: Int,
pagination: Option[Pagination]
): Future[EnhancerToGenes] = {
val tableName = getTableWithPrefixOrDefault(defaultOTSettings.clickhouse.enhancerToGene.name)
val page = pagination.getOrElse(Pagination.mkDefault).offsetLimit
val intervalsQuery = IntervalsQuery(
val e2gQuery = EnhancerToGeneQuery(
chromosome,
start,
end,
Expand All @@ -745,12 +745,12 @@ class Backend @Inject() (implicit
)
val results =
dbRetriever
.executeQuery[Interval, Query](intervalsQuery.query)
.map { intervals =>
if (intervals.length) > 0 then {
Intervals(intervals.head.meta_total, intervals)
.executeQuery[EnhancerToGene, Query](e2gQuery.query)
.map { e2g =>
if (e2g.length > 0) then {
EnhancerToGenes(e2g.head.meta_total, e2g)
} else {
Intervals.empty
EnhancerToGenes.empty
}
}
results
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import esecuele.Column.literal
import esecuele.*
import utils.OTLogging

case class IntervalsQuery(chromosome: String,
start: Int,
end: Int,
tableName: String,
offset: Int,
size: Int
case class EnhancerToGeneQuery(chromosome: String,
start: Int,
end: Int,
tableName: String,
offset: Int,
size: Int
) extends Queryable
with OTLogging {

Expand Down
2 changes: 1 addition & 1 deletion app/models/entities/Configuration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ object Configuration {
diseaseHPO: DbTableSettings,
drug: DbTableSettings,
drugWarnings: DbTableSettings,
enhancerToGene: DbTableSettings,
evidence: EvidenceSettings,
expression: DbTableSettings,
faers: DbTableSettings,
hpo: DbTableSettings,
interaction: DbTableSettings,
intervals: DbTableSettings,
go: DbTableSettings,
harmonic: HarmonicSettings,
l2gPredictions: DbTableSettings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,34 @@ import slick.jdbc.GetResult

case class ResourceScore(name: String, value: Double)

case class Interval(
case class EnhancerToGene(
chromosome: String,
start: Int,
end: Int,
geneId: String,
biosampleName: String,
biosampleId: String,
biosampleFromSourceId: Option[String],
intervalType: String,
distanceToTss: Int,
score: Double,
resourceScore: Vector[ResourceScore],
datasourceId: String,
pmid: String,
studyId: String,
qualityControls: Option[Seq[String]],
meta_total: Long
)

case class Intervals(
case class EnhancerToGenes(
count: Long,
rows: Vector[Interval]
rows: Vector[EnhancerToGene]
)

object Intervals {
val empty: Intervals = Intervals(0, Vector.empty)
implicit val getIntervalRowFromDB: GetResult[Interval] =
GetResult(r => Json.parse(r.<<[String]).as[Interval])
implicit val IntervalImp: OFormat[Interval] = Json.format[Interval]
object EnhancerToGenes {
val empty: EnhancerToGenes = EnhancerToGenes(0, Vector.empty)
implicit val getEnhancerToGeneRowFromDB: GetResult[EnhancerToGene] =
GetResult(r => Json.parse(r.<<[String]).as[EnhancerToGene])
implicit val EnhancerToGeneImp: OFormat[EnhancerToGene] = Json.format[EnhancerToGene]
implicit val ResourceScoreTypeImp: OFormat[ResourceScore] = Json.format[ResourceScore]
}
27 changes: 15 additions & 12 deletions app/models/gql/Objects.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1427,8 +1427,8 @@ object Objects extends OTLogging {
DocumentField("name", "Name of the resource providing the score"),
DocumentField("value", "Score value from the resource")
)
implicit lazy val intervalImp: ObjectType[Backend, Interval] =
deriveObjectType[Backend, Interval](
implicit lazy val enhancerToGeneImp: ObjectType[Backend, EnhancerToGene] =
deriveObjectType[Backend, EnhancerToGene](
ObjectTypeDescription(
"Regulatory enhancer/promoter regions to gene (target) predictions for a specific tissue/cell type based on the integration of experimental sources"
),
Expand All @@ -1450,6 +1450,10 @@ object Objects extends OTLogging {
),
DocumentField("studyId", "Identifier of the study providing the experimental data"),
DocumentField("biosampleName", "Name of the biosample where the interval was identified"),
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The field description for "biosampleName" still refers to "interval" in the phrase "where the interval was identified". For consistency with the refactoring, this should be updated to refer to "regulatory region" or "enhancer/promoter region" instead of "interval".

Suggested change
DocumentField("biosampleName", "Name of the biosample where the interval was identified"),
DocumentField("biosampleName",
"Name of the biosample where the regulatory region was identified"
),

Copilot uses AI. Check for mistakes.
DocumentField("biosampleFromSourceId",
"Identifier of the biosample defined by the datasource provider"
),
DocumentField("qualityControls", "Quality control flags for this interval."),
ReplaceField(
"geneId",
Field("target",
Expand All @@ -1468,11 +1472,10 @@ object Objects extends OTLogging {
),
resolve = r => biosamplesFetcher.deferOpt(r.value.biosampleId)
)
),
ExcludeFields("meta_total")
)
)
implicit lazy val intervalsImp: ObjectType[Backend, Intervals] =
deriveObjectType[Backend, Intervals](
implicit lazy val enhancerToGenesImp: ObjectType[Backend, EnhancerToGenes] =
deriveObjectType[Backend, EnhancerToGenes](
ObjectTypeDescription(
"Collection of regulatory enhancer/promoter regions to gene (target) predictions for a specific tissue/cell type based on the integration of experimental sources"
),
Expand Down Expand Up @@ -2504,18 +2507,18 @@ object Objects extends OTLogging {
ctx => ProteinCodingCoordinatesByVariantDeferred(ctx.value.variantId, ctx.arg(pageArg))
),
Field(
"intervals",
intervalsImp,
"enhancerToGenes",
enhancerToGenesImp,
description = Some(
"Regulatory enhancer/promoter regions to gene (target) predictions overlapping with this variant's location. These intervals link regulatory regions to target genes based on experimental data for specific tissues or cell types."
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The description still uses the old terminology "These intervals link" instead of reflecting the new naming convention. Consider updating to be more consistent with the refactoring, such as "These enhancer-to-gene mappings link" or keeping "intervals" as a more general descriptive term while using "enhancerToGenes" for the field name. The current mix may cause confusion.

Suggested change
"Regulatory enhancer/promoter regions to gene (target) predictions overlapping with this variant's location. These intervals link regulatory regions to target genes based on experimental data for specific tissues or cell types."
"Enhancer-to-gene mappings that link regulatory enhancer/promoter regions to target genes when they overlap this variant's location. These predictions are derived from experimental data for specific tissues or cell types."

Copilot uses AI. Check for mistakes.
),
arguments = pageArg :: Nil,
complexity = Some(complexityCalculator(pageArg)),
resolve = ctx =>
ctx.ctx.getIntervals(ctx.value.chromosome,
ctx.value.position,
ctx.value.position,
ctx.arg(pageArg)
ctx.ctx.getEnhancerToGenes(ctx.value.chromosome,
ctx.value.position,
ctx.value.position,
ctx.arg(pageArg)
)
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

This PR introduces a breaking API change by renaming the GraphQL field from "intervals" to "enhancerToGenes". This will break existing GraphQL queries that use the old field name. Consider: 1) Providing a deprecation period where both field names are supported, or 2) Documenting this as a breaking change in the PR description with migration instructions for API consumers, or 3) Bumping the API version if applicable.

Suggested change
)
)
),
Field(
"intervals",
enhancerToGenesImp,
description = Some(
"Deprecated: use `enhancerToGenes` instead. Regulatory enhancer/promoter regions to gene (target) predictions overlapping with this variant's location."
),
arguments = pageArg :: Nil,
complexity = Some(complexityCalculator(pageArg)),
deprecationReason = Some("Use `enhancerToGenes` instead."),
resolve = ctx =>
ctx.ctx.getEnhancerToGenes(ctx.value.chromosome,
ctx.value.position,
ctx.value.position,
ctx.arg(pageArg)
)

Copilot uses AI. Check for mistakes.
)
),
Expand Down
8 changes: 4 additions & 4 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ ot {
label = "Drug warnings table"
name = "drug_warnings"
}
enhancerToGene {
label = "Enhancer to gene table"
name = "enhancer_to_gene"
}
evidence {
label = "Evidence table"
name = "evidence"
Expand Down Expand Up @@ -88,10 +92,6 @@ ot {
label = "Molecular interaction table"
name = "interaction"
}
intervals {
label = "Intervals table"
name = "intervals"
}
literature {
label = "Literature ocurrences table"
name = "literature"
Expand Down