Skip to content

Commit b267f18

Browse files
committed
package resturucture
1 parent 86fd451 commit b267f18

15 files changed

Lines changed: 367 additions & 356 deletions

File tree

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import sbt.util
2+
13
import scala.collection.Seq
24
// ===== GLOBAL BUILD SETTINGS =====
35
ThisBuild / organization := "com.flowforge"

modules/core/src/main/scala/com/flowforge/core/CompositionPatterns.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.flowforge.core
33
import cats.data.Kleisli
44
import cats.implicits.catsSyntaxTuple2Semigroupal
55
import cats.{ Applicative, Monad }
6-
import com.flowforge.types.FlowForgeError
6+
import com.flowforge.core.types.FlowForgeError
77

88
/**
99
* Advanced composition patterns for FlowForge pipelines

modules/core/src/main/scala/com/flowforge/core/SafeOps.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.flowforge.core
22

3-
import cats.data.{ EitherT, Kleisli, NonEmptyList, OptionT, ValidatedNel }
4-
import cats.{ Applicative, ApplicativeError, Functor, Monad, MonadError }
3+
import cats.data.{EitherT, NonEmptyList, OptionT, ValidatedNel}
54
import cats.syntax.all._
6-
import com.flowforge.types._
7-
import scala.util.{ Failure, Success, Try }
5+
import cats.{Applicative, ApplicativeError, Functor, Monad, MonadError}
6+
87
import scala.concurrent.duration._
8+
import scala.util.{Failure, Success, Try}
99

1010
/**
1111
* Enhanced safe operations with complete monadic support

modules/core/src/main/scala/com/flowforge/core/EffectSystem.scala renamed to modules/core/src/main/scala/com/flowforge/core/algebra/EffectSystem.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
* @version 0.1.0
1010
* @since Aug-2025
1111
*/
12-
package com.flowforge.core
12+
package com.flowforge.core.algebra
1313

1414
import cats.effect.implicits.monadCancelOps_
1515

1616
import scala.annotation.implicitNotFound
1717
import scala.concurrent.duration.FiniteDuration
18-
import scala.concurrent.{ ExecutionContext, Future }
19-
import scala.util.{ Failure, Success }
18+
import scala.concurrent.{ExecutionContext, Future}
19+
import scala.util.{Failure, Success}
2020

2121
/**
2222
* The unified effect system abstraction that forms the foundation of FlowForge.
@@ -649,7 +649,7 @@ object EffectSystem {
649649
*/
650650
implicit val zioEffectSystem: EffectSystem[zio.Task] = {
651651
import zio.interop.catz._
652-
import zio.{ Task, ZIO }
652+
import zio.{Task, ZIO}
653653

654654
new EffectSystem[Task] {
655655
// Functor implementation

modules/core/src/main/scala/com/flowforge/types/TypeClasses.scala renamed to modules/core/src/main/scala/com/flowforge/core/algebra/TypeClasses.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@
3838
* @version 1.0.0
3939
* @since 2024
4040
*/
41-
package com.flowforge
41+
package com.flowforge.core.algebra
4242

4343
import cats.implicits._
44-
import cats.{ Contravariant, Functor }
45-
import com.flowforge.types._
46-
import com.flowforge.validation._
44+
import cats.{Contravariant, Functor}
45+
import com.flowforge.core.types._
46+
4747
import java.nio.charset.StandardCharsets
48-
import java.time.{ Duration, Instant, LocalDate }
49-
import java.util.{ Base64, UUID }
50-
import scala.language.{ higherKinds, implicitConversions }
48+
import java.time.{Duration, Instant, LocalDate}
49+
import java.util.{Base64, UUID}
50+
import scala.language.implicitConversions
5151
import scala.util.Try
5252

5353
/**
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
package com.flowforge.core.error
2+
3+
import com.flowforge.core.types.Metadata
4+
5+
// ===============================
6+
// VALIDATION ERROR TYPES
7+
// ===============================
8+
9+
/**
10+
* Comprehensive validation error hierarchy. Each error type provides specific context about what
11+
* went wrong.
12+
*/
13+
sealed abstract class ValidationError(
14+
val field: String,
15+
val message: String,
16+
val code: String,
17+
val context: Metadata = Map.empty
18+
) extends Product
19+
with Serializable {
20+
21+
/**
22+
* Add context to a validation error. Enables building rich error information.
23+
*/
24+
def withContext(key: String, value: String): ValidationError = {
25+
val newContext = context + (key -> value)
26+
this match {
27+
case e: RequiredFieldError => e.copy(context = newContext)
28+
case e: FormatError => e.copy(context = newContext)
29+
case e: RangeError => e.copy(context = newContext)
30+
case e: LengthError => e.copy(context = newContext)
31+
case e: PatternError => e.copy(context = newContext)
32+
case e: CustomError => e.copy(context = newContext)
33+
case e: CrossFieldError => e.copy(context = newContext)
34+
case e: BusinessRuleError => e.copy(context = newContext)
35+
}
36+
}
37+
38+
/**
39+
* Convert validation error to a user-friendly message.
40+
*/
41+
def toUserMessage: String = s"$field: $message"
42+
43+
/**
44+
* Convert validation error to a detailed technical message.
45+
*/
46+
def toTechnicalMessage: String =
47+
s"ValidationError(field=$field, code=$code, message=$message, context=$context)"
48+
}
49+
50+
/**
51+
* Required field is missing or null.
52+
*/
53+
case class RequiredFieldError(
54+
override val field: String,
55+
override val context: Metadata = Map.empty
56+
) extends ValidationError(
57+
field = field,
58+
message = s"Field '$field' is required but was not provided",
59+
code = "REQUIRED_FIELD_MISSING",
60+
context = context
61+
)
62+
63+
/**
64+
* Field value has invalid format.
65+
*/
66+
case class FormatError(
67+
override val field: String,
68+
expectedFormat: String,
69+
actualValue: String,
70+
override val context: Metadata = Map.empty
71+
) extends ValidationError(
72+
field = field,
73+
message =
74+
s"Field '$field' has invalid format. Expected: $expectedFormat, got: $actualValue",
75+
code = "INVALID_FORMAT",
76+
context = context
77+
)
78+
79+
/**
80+
* Field value is outside expected range.
81+
*/
82+
case class RangeError(
83+
override val field: String,
84+
min: Option[Double],
85+
max: Option[Double],
86+
actualValue: Double,
87+
override val context: Metadata = Map.empty
88+
) extends ValidationError(
89+
field = field,
90+
message = {
91+
val bounds = (min, max) match {
92+
case (Some(minVal), Some(maxVal)) => s"between $minVal and $maxVal"
93+
case (Some(minVal), None) => s"at least $minVal"
94+
case (None, Some(maxVal)) => s"at most $maxVal"
95+
case (None, None) => "within valid range"
96+
}
97+
s"Field '$field' must be $bounds, got: $actualValue"
98+
},
99+
code = "VALUE_OUT_OF_RANGE",
100+
context = context
101+
)
102+
103+
/**
104+
* Field value has invalid length.
105+
*/
106+
case class LengthError(
107+
override val field: String,
108+
minLength: Option[Int],
109+
maxLength: Option[Int],
110+
actualLength: Int,
111+
override val context: Metadata = Map.empty
112+
) extends ValidationError(
113+
field = field,
114+
message = {
115+
val bounds = (minLength, maxLength) match {
116+
case (Some(min), Some(max)) => s"between $min and $max characters"
117+
case (Some(min), None) => s"at least $min characters"
118+
case (None, Some(max)) => s"at most $max characters"
119+
case (None, None) => "valid length"
120+
}
121+
s"Field '$field' must be $bounds, got: $actualLength characters"
122+
},
123+
code = "INVALID_LENGTH",
124+
context = context
125+
)
126+
127+
/**
128+
* Field value doesn't match expected pattern.
129+
*/
130+
case class PatternError(
131+
override val field: String,
132+
pattern: String,
133+
actualValue: String,
134+
override val context: Metadata = Map.empty
135+
) extends ValidationError(
136+
field = field,
137+
message = s"Field '$field' must match pattern '$pattern', got: '$actualValue'",
138+
code = "PATTERN_MISMATCH",
139+
context = context
140+
)
141+
142+
/**
143+
* Custom validation error.
144+
*/
145+
case class CustomError(
146+
override val field: String,
147+
override val message: String,
148+
override val code: String = "CUSTOM_VALIDATION_ERROR",
149+
override val context: Metadata = Map.empty
150+
) extends ValidationError(field, message, code, context)
151+
152+
/**
153+
* Cross-field validation error.
154+
*/
155+
case class CrossFieldError(
156+
fields: List[String],
157+
override val message: String,
158+
override val code: String = "CROSS_FIELD_VALIDATION_ERROR",
159+
override val context: Metadata = Map.empty
160+
) extends ValidationError(
161+
field = fields.mkString(","),
162+
message = message,
163+
code = code,
164+
context = context
165+
)
166+
167+
/**
168+
* Business rule validation error.
169+
*/
170+
case class BusinessRuleError(
171+
rule: String,
172+
override val field: String,
173+
override val message: String,
174+
override val context: Metadata = Map.empty
175+
) extends ValidationError(
176+
field = field,
177+
message = s"Business rule '$rule' violation: $message",
178+
code = "BUSINESS_RULE_VIOLATION",
179+
context = context
180+
)
181+
182+
/**
183+
* Decode error.
184+
*/
185+
case class DecodeError(
186+
override val field: String,
187+
override val context: Metadata = Map.empty
188+
) extends ValidationError(
189+
field = field,
190+
message = s"Cannot decode '$field'",
191+
code = "DECODE_ERROR",
192+
context = context
193+
)
194+
195+
/**
196+
* Timeout error.
197+
*/
198+
case class TimeoutError(
199+
override val field: String,
200+
error: Throwable,
201+
override val context: Metadata = Map.empty
202+
) extends ValidationError(
203+
field = field,
204+
message = s"Time out, duration: $field. [${error.getMessage}]",
205+
code = "TIME_OUT",
206+
context = context
207+
)
208+

modules/core/src/main/scala/com/flowforge/core/CustomMonads.scala renamed to modules/core/src/main/scala/com/flowforge/core/monads/CustomMonads.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
package com.flowforge.core
1+
package com.flowforge.core.monads
22

33
import cats.Monad
44
import cats.syntax.all._
5-
import com.flowforge.types._
5+
import com.flowforge.core.ValidationError
6+
import com.flowforge.core.types._
67

78
import java.time.Instant
89
import scala.annotation.tailrec

modules/core/src/main/scala/com/flowforge/core/CatsDataOps.scala renamed to modules/core/src/main/scala/com/flowforge/core/ops/CatsDataOps.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
package com.flowforge.core
1+
package com.flowforge.core.ops
22

33
import cats.data._
44
import cats.syntax.all._
5-
import cats.{ Applicative, Eval, Functor, Monad }
6-
import com.flowforge.TypeClasses.ConfigReader.PipelineConfig
7-
import com.flowforge.validation.ValidationResult
5+
import cats.{Applicative, Eval, Functor, Monad}
6+
import com.flowforge.core.algebra.TypeClasses.ConfigReader.PipelineConfig
7+
import com.flowforge.core.validation.ValidationResult
8+
import com.flowforge.core.types._
89

910
import java.time.Instant
1011

modules/core/src/main/scala/com/flowforge/core/MonadTransformers.scala renamed to modules/core/src/main/scala/com/flowforge/core/ops/MonadTransformers.scala

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
1-
package com.flowforge.core
1+
package com.flowforge.core.ops
22

33
import cats.data._
4-
import cats.{ Applicative, Functor, Monad, MonadError }
54
import cats.syntax.all._
6-
import com.flowforge.types._
7-
import scala.concurrent.duration.FiniteDuration
8-
import com.flowforge.TypeClasses._
9-
import com.flowforge.TypeClasses.ConfigReader._
10-
import com.flowforge.TypeClasses.DataEncoder._
11-
import com.flowforge.TypeClasses.ContractOps._
12-
import com.flowforge.TypeClasses.Show._
13-
import com.flowforge.TypeClasses.ConfigMapOps._
14-
import com.flowforge.TypeClasses.DataContract._
15-
import com.flowforge.TypeClasses.BinaryDataOps._
16-
import com.flowforge.TypeClasses.DataEncoderOps._
5+
import cats.{Applicative, Functor, Monad}
6+
import com.flowforge.core.algebra.TypeClasses.ConfigReader._
7+
import com.flowforge.core.ValidationError
8+
import com.flowforge.core.types._
179

1810
/**
1911
* Complete monad transformers integration for FlowForge

modules/core/src/main/scala/com/flowforge/core/package.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@
3434
*/
3535
package com.flowforge
3636

37-
import scala.language.{ higherKinds, implicitConversions }
37+
import scala.language.{higherKinds, implicitConversions}
3838
import scala.concurrent.duration.FiniteDuration
39-
import scala.util.{ Failure, Success, Try }
40-
import java.time.{ Instant, LocalDate }
39+
import scala.util.{Failure, Success, Try}
40+
import java.time.{Instant, LocalDate}
4141
import java.util.UUID
42-
43-
import cats.data.{ Kleisli, NonEmptyList, Reader, State, Validated, ValidatedNel, Writer }
44-
import cats.effect.{ Clock, Resource }
45-
import cats.{ Applicative, Functor, Monad }
42+
import cats.data.{Kleisli, NonEmptyList, Reader, State, Validated, ValidatedNel, Writer}
43+
import cats.effect.{Clock, Resource}
44+
import cats.{Applicative, Functor, Monad}
4645
import cats.implicits._
46+
import com.flowforge.core.algebra.{EffectSystem, TypeClasses}
4747

4848
/**
4949
* The core package object provides the main API for FlowForge core functionality.
@@ -598,7 +598,7 @@ package object core {
598598

599599
// Import syntax extensions
600600
import validation.ValidationSyntax
601-
import TypeClasses.{ BinaryDataOps, ConfigMapOps, ContractOps, DataEncoderOps }
601+
import com.flowforge.core.algebra.TypeClasses.{ BinaryDataOps, ConfigMapOps, ContractOps, DataEncoderOps }
602602
import pipeline.{ PipelineComponentOps, PipelineOps }
603603

604604
// ===============================

0 commit comments

Comments
 (0)