Clean up schema version handling.
[?]
Oct 22, 2016, 6:59 PM
7VGYLTMURLVSVUYFW7TCRZTDQ6RE2EPSPPA43XKHDOBFWYVVSJHQCDependencies
- [2]
FXJQACESEnsure that auction is not ended at the time of bid - [3]
GKLIPHR5Fix error in parsing of event metadata - [4]
2LZYVHFSUpgrade to Stack-based build in Docker - [5]
2XQD6KKKAdd invitation logic and clean up DBProg error handling. - [6]
5OI44E4EAdd authentication to auction search. - [7]
SPJCFHXWUpdate shell scripts to point to https://aftok.com and prompt for input. - [8]
HYV3VQADFix a couple of stupid typos. - [9]
ASF3UPJLAdd auction creation and bid handlers - [10]
NLZ3JXLOFix formatting with stylish-haskell. - [11]
O5FVTOM6Undo JSON silliness, enable a couple more routes. - [12]
4ZLEDBK7Initial attempts at dockerizing, cabal isn't cooperating. - [13]
Z3MK2PJ5Add GET handler for retrieving auction data. - [14]
RPAJLHMTChange to use UUIDs instead of ints for primary keys. - [15]
JEOPOOPTDockerfile now builds correctly. - [16]
XTBSG4C7Adding serveJSON combinator to eliminate some boilerplate from handlers. - [17]
M3KUPGZKAdd invitation email template. - [18]
BWN72T44Don't accept work timestamp from an external source. - [19]
QMRKFEPGRefactor QDB to use a free monad algebra instead. - [20]
XJ4EYMIHLet curl prompt for http password, rather than bash. - [21]
7HPY3QPFFix linting errors. (yay hlint!) - [22]
A6HKMINBAttempting to improve JSON handling. - [23]
HALRDT2FAdded initial auction create route. - [24]
RN7EI6INUpdate database layer to use CreditTo - [25]
UILI6PILThe route-based logStart/logStop is nicer. - [26]
Z7KS5XHHVery WIP. Wow. - [27]
POX3UAMTEnabling logging of time to contributor/project accounts - [28]
GCVQD44VCreate amends endpoint, switch to UUID primary keys - [29]
O722AOKEAdd route to allow crediting of events to users/projects. - [*]
W35DDBFYFactor common JSON conversions up into client lib module. - [*]
2G3GNDDUEvent logging is now functioning in postgres.
Change contents
- replacement in Dockerfile at line 17
ADD ./aftok.cabal /opt/aftok/aftok.cabalADD ./stack.yaml /opt/aftok/stack.yamlADD ./lib /opt/aftok/libADD ./server /opt/aftok/serverADD ./test /opt/aftok/testRUN mkdir -p /opt/aftok/bin - edit in Dockerfile at line 19
ADD ./aftok.cabal /opt/aftok/aftok.cabalADD ./docker/stack.yaml /opt/aftok/stack.yaml - replacement in Dockerfile at line 25
# Install and build aftok-server sourcesRUN stack buildADD ./lib /opt/aftok/libADD ./server /opt/aftok/serverADD ./test /opt/aftok/test# build and install and aftok-server sourcesRUN stack install - replacement in docker/aftok-server.sh at line 3
/opt/aftok/dist/build/aftok-server/aftok-server[5.1544]/opt/aftok/bin/aftok-server - file addition: stack.yaml[5.1510]
flags: {}packages:- '.'extra-deps:- snaplet-postgresql-simple-0.6.0.4- resource-pool-catchio-0.2.1.0resolver: lts-5.3#allow-newer: truelocal-bin-path: /opt/aftok/bin - replacement in lib/Aftok/Json.hs at line 54
versioned :: Version -> Value -> Valueversioned ver v = object [ "schemaVersion" .= tshow ver, "value" .= v ]versioned :: Version -> Object -> Valueversioned ver o = Object $ uncurry O.insert ("schemaVersion" .= tshow ver) o - replacement in lib/Aftok/Json.hs at line 61
unversion :: (Version -> Value -> Parser a) -> Value -> Parser aunversion f (Object v) = doverstr <- v .: "schemaVersion"unversion :: String -> (Version -> Object -> Parser a) -> Value -> Parser aunversion name f o = doverstr <- withObject name (.: "schemaVersion") o - replacement in lib/Aftok/Json.hs at line 65[5.129]→[5.4690:4717](∅→∅),[5.460]→[5.4690:4717](∅→∅),[5.4690]→[5.4690:4717](∅→∅),[5.4717]→[5.1588:1604](∅→∅),[5.1604]→[5.4734:4806](∅→∅),[5.4734]→[5.4734:4806](∅→∅)
v .: "value" >>= f versunversion _ x =fail $ show x <> " did not contain the expected version information."withObject name (f vers) o - replacement in lib/Aftok/Json.hs at line 71
v1 :: Value -> Valuev1 :: Object -> Value - replacement in lib/Aftok/Json.hs at line 74
v2 :: Value -> Valuev2 :: Object -> Value - replacement in lib/Aftok/Json.hs at line 77
unv1 :: String -> (Value -> Parser a) -> Value -> Parser aunv1 name f = unversion $ \x -> case x ofVersion 1 0 -> f_ -> badVersion name xunv1 :: String -> (Object -> Parser a) -> Value -> Parser aunv1 name f = unversion name $ p wherep (Version 1 0) = fp ver = badVersion name ver - replacement in lib/Aftok/Json.hs at line 82
badVersion :: String -> Version -> Value -> Parser abadVersion :: forall v a. String -> Version -> v -> Parser a - edit in lib/Aftok/Json.hs at line 85
-- convenience function to produce Object rather than Valueobj :: [Pair] -> Objectobj = O.fromList - replacement in lib/Aftok/Json.hs at line 95[5.6666]→[5.1049:1102](∅→∅),[5.1102]→[5.5274:5318](∅→∅),[5.6721]→[5.5274:5318](∅→∅),[5.5274]→[5.5274:5318](∅→∅),[5.5318]→[5.1682:1693](∅→∅),[5.1682]→[5.1682:1693](∅→∅)
object [ "projectId" .= tshow (pid ^. _ProjectId), "project" .= projectJSON project]obj [ "projectId" .= tshow (pid ^. _ProjectId), "project" .= projectJSON project] - replacement in lib/Aftok/Json.hs at line 101
object [ "projectId" .= tshow (pid ^. _ProjectId) ]obj [ "projectId" .= tshow (pid ^. _ProjectId) ] - replacement in lib/Aftok/Json.hs at line 105
object [ "projectName" .= (p ^. projectName), "inceptionDate" .= (p ^. inceptionDate), "initiator" .= tshow (p ^. (P.initiator._UserId))]obj [ "projectName" .= (p ^. projectName), "inceptionDate" .= (p ^. inceptionDate), "initiator" .= tshow (p ^. (P.initiator._UserId))] - replacement in lib/Aftok/Json.hs at line 112
object [ "auctionId" .= tshow (pid ^. _AuctionId) ]obj [ "auctionId" .= tshow (pid ^. _AuctionId) ] - replacement in lib/Aftok/Json.hs at line 116[5.592]→[5.592:782](∅→∅),[5.782]→[5.1168:1179](∅→∅),[5.1696]→[5.1168:1179](∅→∅),[5.1168]→[5.1168:1179](∅→∅)
object [ "projectId" .= tshow (x ^. (A.projectId._ProjectId)), "initiator" .= tshow (x ^. (A.initiator._UserId)), "raiseAmount" .= (x ^. (raiseAmount._Satoshi))]obj [ "projectId" .= tshow (x ^. (A.projectId._ProjectId)), "initiator" .= tshow (x ^. (A.initiator._UserId)), "raiseAmount" .= (x ^. (raiseAmount._Satoshi))] - replacement in lib/Aftok/Json.hs at line 123
object [ "bidId" .= tshow (pid ^. _BidId) ]obj [ "bidId" .= tshow (pid ^. _BidId) ] - replacement in lib/Aftok/Json.hs at line 126
creditToJSON (CreditToAddress addr) = v2 $ object [ "creditToAddress" .= (addr ^. _BtcAddr) ]creditToJSON (CreditToUser uid) = v2 $ object [ "creditToUser" .= tshow (uid ^. _UserId) ]creditToJSON (CreditToProject pid) = v2 $ object [ "creditToProject" .= projectIdJSON pid ]creditToJSON (CreditToAddress addr) = v2 $ obj [ "creditToAddress" .= (addr ^. _BtcAddr) ]creditToJSON (CreditToUser uid) = v2 $ obj [ "creditToUser" .= tshow (uid ^. _UserId) ]creditToJSON (CreditToProject pid) = v2 $ obj [ "creditToProject" .= projectIdJSON pid ] - replacement in lib/Aftok/Json.hs at line 136
in toJSON $ fmap payoutsRec (MS.assocs m)in obj $ [ "payouts" .= fmap payoutsRec (MS.assocs m) ] - replacement in lib/Aftok/Json.hs at line 144
in toJSON $ fmap widxRec (MS.assocs widx)in obj $ [ "workIndex" .= fmap widxRec (MS.assocs widx) ] - replacement in lib/Aftok/Json.hs at line 148
object [ "eventId" .= tshow eid ]obj [ "eventId" .= tshow eid ] - replacement in lib/Aftok/Json.hs at line 156[5.1665]→[5.1665:1706](∅→∅),[5.1706]→[5.256:294](∅→∅),[5.294]→[5.1992:2031](∅→∅),[5.1992]→[5.1992:2031](∅→∅)
object [ "creditTo" .= creditToJSON c, "event" .= logEventJSON ev, "eventMeta" .= m]obj [ "creditTo" .= creditToJSON c, "event" .= logEventJSON ev, "eventMeta" .= m] - replacement in lib/Aftok/Json.hs at line 163
object [ "amendmentId" .= tshow aid ]obj [ "amendmentId" .= tshow aid ] - edit in lib/Aftok/Json.hs at line 169
parseCreditTo :: Value -> Parser CreditToparseCreditTo = unversion "CreditTo" $ p wherep (Version 1 0) = parseCreditToV1p (Version 2 0) = parseCreditToV2p ver = badVersion "EventAmendment" verparseCreditToV1 :: Object -> Parser CreditToparseCreditToV1 x = CreditToAddress <$> (parseBtcAddrJson =<< (x .: "btcAddr"))parseCreditToV2 :: Object -> Parser CreditToparseCreditToV2 o =let parseCreditToAddr o' =fmap CreditToAddress . parseBtcAddrJson <$> O.lookup "creditToAddress" o'parseCreditToUser o' =fmap (CreditToUser . UserId) . parseUUID <$> O.lookup "creditToUser" o'parseCreditToProject o' =fmap (CreditToProject . ProjectId) . parseUUID <$> O.lookup "creditToProject" o'notFound = fail $ "Value " <> show o <> " does not represent a CreditTo value."parseV v = (parseCreditToAddr v <|> parseCreditToUser v <|> parseCreditToProject v)in fromMaybe notFound $ parseV o - replacement in lib/Aftok/Json.hs at line 195
parsePayoutsJSON = unversion $ \ver -> case ver of(Version 1 _) -> \v -> Payouts . MS.mapKeys (CreditToAddress . BtcAddr) <$> parseJSON v(Version 2 0) -> \v -> doxs <- parseJSON vlet parsePayoutRecord x = (,) <$> (parseCreditTo =<< (x .: "creditTo"))<*> x .: "payoutRatio"Payouts . MS.fromList <$> traverse parsePayoutRecord xs_ -> badVersion "Payouts" verparsePayoutsJSON = unversion "Payouts" $ p wherep :: Version -> Object -> Parser Payoutsp (Version 1 _) v = Payouts . MS.mapKeys (CreditToAddress . BtcAddr) <$> parseJSON (Object v)p (Version 2 0) v =let parsePayoutRecord x = (,) <$> (parseCreditToV2 =<< (x .: "creditTo")) <*> x .: "payoutRatio"in Payouts . MS.fromList <$> (traverse parsePayoutRecord =<< parseJSON (Object v))p ver x = badVersion "Payouts" ver x - replacement in lib/Aftok/Json.hs at line 204
parseEventAmendment t = unversion $ \v -> case v ofVersion 1 0 -> parseEventAmendmentV1 tVersion 2 0 -> parseEventAmendmentV2 t_ -> badVersion "EventAmendment" vparseEventAmendment t = unversion "EventAmendment" $ p wherep (Version 1 _) = parseEventAmendmentV1 tp (Version 2 0) = parseEventAmendmentV2 tp ver = badVersion "EventAmendment" ver - replacement in lib/Aftok/Json.hs at line 209
parseEventAmendmentV1 :: ModTime -> Value -> Parser EventAmendmentparseEventAmendmentV1 t v@(Object x) =parseEventAmendmentV1 :: ModTime -> Object -> Parser EventAmendmentparseEventAmendmentV1 t o = - replacement in lib/Aftok/Json.hs at line 212
parseA "timeChange" = TimeChange t <$> x .: "eventTime"parseA "addrChange" = CreditToChange t <$> parseCreditTo vparseA "metadataChange" = MetadataChange t <$> x .: "eventMeta"parseA "timeChange" = TimeChange t <$> o .: "eventTime"parseA "addrChange" = CreditToChange t <$> parseCreditToV1 oparseA "metadataChange" = MetadataChange t <$> o .: "eventMeta" - replacement in lib/Aftok/Json.hs at line 216[5.4481]→[5.2392:2428](∅→∅),[5.2392]→[5.2392:2428](∅→∅),[5.2428]→[5.4482:4510](∅→∅),[5.4510]→[5.2456:2512](∅→∅),[5.2456]→[5.2456:2512](∅→∅)
in x .: "amendment" >>= parseAparseEventAmendmentV1 _ x =fail $ "Value " <> show x <> " is not a JSON object."in o .: "amendment" >>= parseA - replacement in lib/Aftok/Json.hs at line 218
parseEventAmendmentV2 :: ModTime -> Value -> Parser EventAmendmentparseEventAmendmentV2 t v@(Object x) =parseEventAmendmentV2 :: ModTime -> Object -> Parser EventAmendmentparseEventAmendmentV2 t o = - replacement in lib/Aftok/Json.hs at line 221
parseA "timeChange" = TimeChange t <$> x .: "eventTime"parseA "creditToChange" = CreditToChange t <$> parseCreditTo vparseA "metadataChange" = MetadataChange t <$> x .: "eventMeta"parseA "timeChange" = TimeChange t <$> o .: "eventTime"parseA "creditToChange" = CreditToChange t <$> parseCreditToV2 oparseA "metadataChange" = MetadataChange t <$> o .: "eventMeta" - replacement in lib/Aftok/Json.hs at line 225
in x .: "amendment" >>= parseAin o .: "amendment" >>= parseA - edit in lib/Aftok/Json.hs at line 227
parseEventAmendmentV2 _ x =fail $ "Value " <> show x <> " is not a JSON object." - edit in lib/Aftok/Json.hs at line 236[5.4851]→[5.3478:3479](∅→∅),[5.3478]→[5.3478:3479](∅→∅),[5.3479]→[5.295:539](∅→∅),[5.539]→[5.3479:3605](∅→∅),[5.3479]→[5.3479:3605](∅→∅),[5.2003]→[5.6554:6555](∅→∅),[5.3605]→[5.6554:6555](∅→∅),[5.6554]→[5.6554:6555](∅→∅),[5.6555]→[5.3606:3825](∅→∅),[5.3825]→[5.4852:4888](∅→∅)
parseCreditTo :: Value -> Parser CreditToparseCreditTo = unversion $ \v -> case v ofVersion 1 0 -> withObject "BtcAddr" parseCreditToV1Version 2 0 -> withObject "CreditTo" parseCreditToV2_ -> badVersion "EventAmendment" vparseCreditToV1 :: Object -> Parser CreditToparseCreditToV1 x = CreditToAddress <$> (parseBtcAddrJson =<< (x .: "btcAddr"))parseCreditToV2 :: Object -> Parser CreditToparseCreditToV2 x =let parseCreditToAddr (Object x') = doaddrText <- O.lookup "creditToAddress" x'pure (CreditToAddress <$> parseBtcAddrJson addrText)parseCreditToAddr _ = Nothing - edit in lib/Aftok/Json.hs at line 237[5.3863]→[5.4889:5073](∅→∅),[5.5073]→[5.3946:3947](∅→∅),[5.3946]→[5.3946:3947](∅→∅),[5.3947]→[5.5074:5164](∅→∅),[5.5164]→[5.4036:4290](∅→∅),[5.4036]→[5.4036:4290](∅→∅)
parseCreditToUser (Object x') = douserText <- O.lookup "creditToUser" x'pure (CreditToUser . UserId <$> parseUUID userText)parseCreditToUser _ = Nothing--parseCreditToProject (Object x') = NothingparseCreditToProject _ = NothingnotFound = fail $ "Value " <> show x <> " does not represent a CreditTo value."parseV v = (parseCreditToAddr v <|> parseCreditToUser v <|> parseCreditToProject v)in dobody <- x .: "creditTo"fromMaybe notFound $ parseV body - replacement in lib/Aftok/Json.hs at line 238
parseLogEntry f = unversion parseLogEntry' whereparseLogEntry' (Version 2 0) (Object x) = docreditTo' <- x .: "creditTo" >>= parseCreditToeventMeta' <- x .:? "eventMeta"parseLogEntry f = unversion "LogEntry" p wherep (Version 2 0) o = docreditTo' <- o .: "creditTo" >>= parseCreditToV2eventMeta' <- o .:? "eventMeta" - replacement in lib/Aftok/Json.hs at line 244
parseLogEntry' v x = badVersion "LogEntry" v xp v o = badVersion "LogEntry" v o - replacement in scripts/log_end.sh at line 8
curl -v -k -u $USER -X POST -d "{\"creditTo\": {\"creditToUser\": \"$UID\"}}" "https://aftok.com/projects/$PID/logEnd"[5.562]curl -v -k -u $USER -X POST -d "{\"schemaVersion\": \"2.0\", \"creditTo\": {\"creditToUser\": \"$UID\"}}" "https://aftok.com/projects/$PID/logEnd" - replacement in scripts/log_start.sh at line 8
curl -v -k -u $USER -X POST -d "{\"creditTo\": {\"creditToUser\": \"$UID\"}}" "https://aftok.com/projects/$PID/logStart"[5.803]curl -v -k -u $USER -X POST -d "{\"schemaVersion\": \"2.0\", \"creditTo\": {\"creditToUser\": \"$UID\"}}" "https://aftok.com/projects/$PID/logStart" - replacement in server/Aftok/Snaplet/Auctions.hs at line 30
auctionCreateParser = unv1 "auctions" $ \v ->case v of(Object o) -> CA <$> o .: "raiseAmount"<*> o .: "auctionEnd"_ -> mzeroauctionCreateParser = unv1 "auctions" p wherep o = CA <$> o .: "raiseAmount" <*> o .: "auctionEnd" - replacement in server/Aftok/Snaplet/Auctions.hs at line 34
bidCreateParser uid t = unv1 "bids" $ \v ->case v of(Object o) -> Bid uid <$> (Seconds <$> o .: "bidSeconds")<*> (Satoshi <$> o .: "bidAmount")<*> pure t_ -> mzerobidCreateParser uid t = unv1 "bids" p wherep o = Bid uid <$> (Seconds <$> o .: "bidSeconds")<*> (Satoshi <$> o .: "bidAmount")<*> pure t - edit in server/Aftok/Snaplet/Auctions.hs at line 63