Skip to content

Commit 9f03cb9

Browse files
committed
something-is-working-trying-sql
1 parent 5f019d4 commit 9f03cb9

File tree

2 files changed

+109
-70
lines changed

2 files changed

+109
-70
lines changed

govtool/backend/src/VVA/API/SyncAiResponseType.hs

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66

77
module VVA.API.SyncAiResponseType where
88

9-
import Data.Maybe (fromMaybe)
10-
import GHC.Generics (Generic)
11-
import Data.Text (Text)
9+
import Data.Maybe (fromMaybe)
10+
import GHC.Generics (Generic)
11+
import Data.Text (Text)
1212
import qualified Data.Text (stripPrefix)
13-
import Data.Aeson
13+
import Data.Aeson
1414
import qualified Data.Aeson.Types as Aeson
15-
import Data.Aeson.Types (Parser)
15+
import Data.Aeson.Types (Parser)
1616
import qualified Data.Aeson.Key as Key
17-
import Data.OpenApi (ToSchema)
18-
import Control.Applicative ((<|>))
17+
import Data.OpenApi (ToSchema)
18+
import Control.Applicative ((<|>))
19+
import Data.Scientific
1920

2021
-- Helper: safe lookup for Maybe Value
2122
(.::?) :: Maybe Value -> Text -> Parser (Maybe Value)
@@ -37,46 +38,48 @@ instance ToJSON TextOrValue where
3738
toJSON (TextOrValue t) = String t
3839

3940
data SearchAiResponse = SearchAiResponse
40-
{ data_ :: Maybe [DRepData]
41+
{ elements :: Maybe [DRepData]
4142
, meta :: Meta
4243
, pagination :: Pagination
4344
} deriving (Show, Generic, ToSchema)
4445

4546
instance FromJSON SearchAiResponse where
4647
parseJSON = genericParseJSON defaultOptions { fieldLabelModifier = fixData }
47-
where fixData "data_" = "data"
48+
where fixData "elements" = "data"
4849
fixData other = other
4950
instance ToJSON SearchAiResponse where
5051
toJSON = genericToJSON defaultOptions { fieldLabelModifier = fixData }
51-
where fixData "data_" = "data"
52+
where fixData "elements" = "data"
5253
fixData other = other
5354

5455
data DRepData = DRepData
55-
{ drepId :: Text
56-
-- Missing:
57-
-- , dRepHash :: Text
58-
-- , view :: Text
59-
-- , isScriptBased :: Bool
60-
, url :: Maybe Text
61-
-- Missing:
62-
-- , dataHash :: Maybe Text
63-
-- , deposit :: Integer
64-
-- , votingPower :: Double -- We might need to multiply this by 1e6 to get the actual voting power + Int
65-
, status :: Text
66-
-- Missing:
67-
-- , type :: DRepType
68-
-- , latestTxHash :: Maybe Text
56+
{ deposit :: Scientific
57+
, drepId :: Text
58+
, givenName :: Maybe Text
59+
, identityRefs :: [Reference]
60+
, imageHash :: Maybe TextOrValue
61+
, imageUrl :: Maybe TextOrValue
62+
, isScriptBased :: Bool
6963
-- , latestRegistrationDate :: UTCTime
70-
-- , metadataError :: Maybe Text
71-
, paymentAddress :: Maybe TextOrValue
72-
, givenName :: Maybe Text
73-
, objectives :: Maybe Text
74-
, motivations :: Maybe Text
75-
, qualifications :: Maybe TextOrValue
76-
, imageUrl :: Maybe TextOrValue
77-
, imageHash :: Maybe TextOrValue
78-
, linkReferences :: [Reference]
79-
, identityReferences :: [Reference]
64+
, latestRegistrationDate :: Maybe Text
65+
, latestTxHash :: Maybe Text
66+
, linkReferences :: [Reference]
67+
, metadataError :: Maybe Text
68+
, metadataHash :: Maybe Text
69+
, motivations :: Maybe Text
70+
, objectives :: Maybe Text
71+
, paymentAddress :: Maybe TextOrValue
72+
, qualifications :: Maybe TextOrValue
73+
-- , status :: DRepStatus
74+
, status :: Maybe Text
75+
-- , type :: DRepType
76+
, type_ :: Maybe Text
77+
, url :: Maybe Text
78+
, view :: Text
79+
, votingPower :: Maybe Integer -- We might need to multiply this by 1e6 to get the actual voting power + Int
80+
-- THOSE ARE WEIRD FIELDS, NOT USED FOR NOW
81+
-- , drepHash :: Text
82+
-- , dataHash :: Maybe Text
8083
} deriving (Show, Generic, ToSchema, ToJSON)
8184

8285
instance FromJSON DRepData where
@@ -87,9 +90,8 @@ instance FromJSON DRepData where
8790
objectives <- v .: "objectives"
8891
status <- v .: "status"
8992
url <- v .:? "url"
90-
-- votingPower <- (v .: "votingPower" <|> (v .: "metrics" >>= (.: "votingPower")))
9193

92-
--
94+
-- dRep data manipulation:
9395
mMeta <- v .:? "metadata"
9496
mJsonMeta <- mMeta .::? "json_metadata"
9597
mBody <- mJsonMeta .::? "body"
@@ -144,9 +146,21 @@ instance FromJSON DRepData where
144146
, filter (\ref -> refType ref == Just "Identity") refs
145147
)
146148

149+
-- Placeholders for fields not yet implemented
150+
deposit <- pure 123456789
151+
latestRegistrationDate <- pure (Just "2023-10-01T00:00:00Z")
152+
latestTxHash <- pure Nothing
153+
isScriptBased <- pure False
154+
metadataError <- pure Nothing
155+
metadataHash <- pure Nothing
156+
type_ <- pure (Just "DRep")
157+
view <- pure "https://example.com/view"
158+
votingPower <- pure (Just 100)
159+
147160
pure $ DRepData
148-
drepId motivations givenName objectives status url -- votingPower
149-
imageUrl imageHash paymentAddress qualifications linkRefs identityRefs
161+
deposit drepId givenName identityRefs imageHash imageUrl isScriptBased latestRegistrationDate
162+
latestTxHash linkRefs metadataError metadataHash motivations objectives paymentAddress
163+
qualifications status type_ url view votingPower
150164

151165
data Reference = Reference
152166
{ refType :: Maybe Text -- "@type"

govtool/backend/src/VVA/DRep.hs

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import qualified Data.Map as M
2222
import Data.Maybe (fromMaybe, isJust, isNothing)
2323
import Data.Scientific
2424
import Data.String (fromString)
25-
import Data.Text (Text, pack, unpack, intercalate, pack)
25+
import Data.Text (Text, pack, unpack, intercalate, pack, isPrefixOf, drop)
2626
import qualified Data.Text.Encoding as Text
2727
import Data.Time
2828

@@ -36,7 +36,7 @@ import qualified VVA.Proposal as Proposal
3636
import VVA.Types (AppError (CriticalError), DRepInfo (..), DRepRegistration (..),
3737
DRepStatus (..), DRepType (..), Proposal (..), Vote (..),
3838
DRepVotingPowerList (..))
39-
import VVA.API.SyncAiResponseType (SearchAiResponse)
39+
import VVA.API.SyncAiResponseType (SearchAiResponse(..), DRepData(..))
4040

4141
import Network.HTTP.Client (newManager, parseRequest, httpLbs, RequestBody(..), method,
4242
requestHeaders, requestBody, responseBody, Manager, Request, Response)
@@ -134,36 +134,6 @@ listDReps mSearchQuery = withPool $ \conn -> do
134134
| Data.Maybe.isJust (queryUrl result) = DRep
135135
]
136136

137-
drepAiSearch ::
138-
(Has VVAConfig r, MonadReader r m, MonadIO m, MonadError AppError m) =>
139-
Maybe Text -- ^ search query
140-
-> Int -- ^ page
141-
-> Int -- ^ limit
142-
-> m SearchAiResponse
143-
drepAiSearch query page limit = do
144-
vvaConfig <- asks getter
145-
result <- liftIO $ do
146-
manager <- newManager tlsManagerSettings
147-
initialRequest <- parseRequest "https://api.syncgovhub.com/api/drep/ai"
148-
let body = encode $ object
149-
[ "query" .= query
150-
, "page" .= page
151-
, "limit" .= limit
152-
]
153-
request = initialRequest
154-
{ method = "POST"
155-
, requestHeaders =
156-
[ ("Content-Type", "application/json")
157-
, ("x-api-key", Text.encodeUtf8 (pack (syncAiKey vvaConfig)))
158-
]
159-
, requestBody = RequestBodyLBS body
160-
}
161-
response <- httpLbs request manager
162-
return $ eitherDecode (responseBody response)
163-
case result of
164-
Left err -> throwError $ CriticalError ("Could not parse the dReps: " <> pack err)
165-
Right val -> return val
166-
167137
getVotingPowerSql :: SQL.Query
168138
getVotingPowerSql = sqlFrom $(embedFile "sql/get-voting-power.sql")
169139

@@ -296,3 +266,58 @@ getDRepsVotingPowerList identifiers = withPool $ \conn -> do
296266
| (view, hashRaw, votingPower', givenName) <- results
297267
, let votingPower = floor @Scientific votingPower'
298268
]
269+
270+
271+
-- 1. Fetch from 3rd party
272+
fetchDRepAiData ::
273+
(Has VVAConfig r, MonadReader r m, MonadIO m, MonadError AppError m) =>
274+
Maybe Text -- ^ search query
275+
-> Int -- ^ page
276+
-> Int -- ^ limit
277+
-> m SearchAiResponse
278+
fetchDRepAiData query page limit = do
279+
vvaConfig <- asks getter
280+
result <- liftIO $ do
281+
manager <- newManager tlsManagerSettings
282+
initialRequest <- parseRequest "https://api.syncgovhub.com/api/drep/ai"
283+
let body = encode $ object
284+
[ "query" .= query
285+
, "page" .= page
286+
, "limit" .= limit
287+
]
288+
request = initialRequest
289+
{ method = "POST"
290+
, requestHeaders =
291+
[ ("Content-Type", "application/json")
292+
, ("x-api-key", Text.encodeUtf8 (pack (syncAiKey vvaConfig)))
293+
]
294+
, requestBody = RequestBodyLBS body
295+
}
296+
response <- httpLbs request manager
297+
return $ eitherDecode (responseBody response)
298+
case result of
299+
Left err -> throwError $ CriticalError ("Could not parse the dReps: " <> pack err)
300+
Right val -> return val
301+
302+
-- 2. Manipulate/transform
303+
manipulateDRepAiData :: SearchAiResponse -> SearchAiResponse
304+
manipulateDRepAiData resp = resp { elements = fmap (map cutDrepId) (elements resp) }
305+
where
306+
cutDrepId d =
307+
let dId = drepId d
308+
in d { drepId = if Data.Text.isPrefixOf "22" dId then Data.Text.drop 2 dId else dId }
309+
310+
-- 3. Enrich with SQL data
311+
enrichDRepDataWithDb ::
312+
(Monad m) =>
313+
SearchAiResponse -> m SearchAiResponse
314+
enrichDRepDataWithDb = return
315+
316+
-- 4. Compose them in your endpoint/handler
317+
drepAiSearch ::
318+
(Has VVAConfig r, MonadReader r m, MonadIO m, MonadError AppError m) =>
319+
Maybe Text -> Int -> Int -> m SearchAiResponse
320+
drepAiSearch query page limit = do
321+
aiData <- fetchDRepAiData query page limit
322+
let manipulated = manipulateDRepAiData aiData
323+
enrichDRepDataWithDb manipulated

0 commit comments

Comments
 (0)