Follow the types! Too many functions were taking Value as their input rather than Object (for all versioned data structures.) This ended up cleaning up code in a number of unexpected places.
7VGYLTMURLVSVUYFW7TCRZTDQ6RE2EPSPPA43XKHDOBFWYVVSJHQC FXJQACESPGTLPG5ELXBU3M3OQXUZQQIR7HPIEHQ3FNUTMWVH4WBAC GKLIPHR5YOBKEMC4744J3WYYFLPFXMZEOLC6Z26QXAG4IM2HQVEQC 2LZYVHFSGAHDZD4TKSSHUHYR3N6LJFDSWUV2SFVP3GXNT7Y43BNQC M3KUPGZK2UTW4FG3Q632K7P7MI4FVWD5TTIP45UTI3E72UKOWJBAC 4ZLEDBK7VGLKFUPENAFLUJYNFLKFYJ3TREPQ7P6PKMYGJUXB55HQC JEOPOOPTQ7ESS2IG7KROXNF67RB37X63GVM6UK3FYMZG6VUUQG2AC GCVQD44VRPQVKPZEPIC4AOIXLJIG2ZMV3QI2Y7KALUT6NVUBSGSAC W35DDBFYF6Z4ZPCFEO5RPAONZLYCSNTXUSTS6FIUUVZHCI6Q7GHAC XTBSG4C7SCZUFOU2BTNFR6B6TCGYI35BWUV4PVTS3N7KNH5VEARQC A6HKMINBNGQLLX4QJMYWKQ4JAEHVJ4HIRVDKPPDI3FJUO2AAB7OQC O722AOKEWXWJPRHGJREU6QPW7HEFPPRETZIAADZ2RMAXHARCNEKAC Z3MK2PJ5U222DXRS22WCDHVPZ7HVAR3HOCUNXIGX6VMEPBQDF6PQC NLZ3JXLOOIL37O3RRQWXHNPNSNEOOLPD6MCB754BEBECQB3KGR2AC POX3UAMTGCNS3SU5I6IKDNCCSHEAUSFBZ3WCMQ3EXKPNXETOI6BAC 2XQD6KKKD6QVHFHAEMVE3XXY7X2T7BLTLL7XIILZAXNJJH2YONUQC 7HPY3QPFPN35PSPUBVNW2GTFB3CBQZBST4J2BAVJ7QMXLIUN52JAC O5FVTOM6YFBLEPF3S576K6IMT6ZZ5VQCSB3YVXNS4CKBITKCRZ7AC ASF3UPJLCX7KIUCNJD5KAXSPDXCUEJHLL4HBRTRUBPCW73IXOCWQC Z7KS5XHHC6PAMTVBHXY7KUSS3BWAOU6FSYIITUCFOOJZU4OUJHBAC RN7EI6INGUUHGMNY5RU3NH56WPLRZY5ZMYDNFMNE3TGV4ESFLQIAC RPAJLHMTUJU4AYNBOHVGHGGB4NY2NLY3BVPYN5FMWB3ZIMAUQHCQC UILI6PILCRDPZ3XYA54LGIGPSU7ERWNHCE7R3CE64ZEC7ONOEMOQC BWN72T44GRRZ6K2OPN56FTLNEB7J7AGC7T2U5HSMLEKUPGJP2NUAC SPJCFHXWUHL5DPU72R6MLMVYCRL4YNOMGTDXRFL6GZPN5KOHAW7AC 2G3GNDDUOVPF45PELJ65ZB2IXEHJJXJILFRVHZXGPXUL4BVNZJFQC HALRDT2F22DAQ54M334YSKD2XJCAXDXEZPDKGMOWKH7XELBAS6MAC 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
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
v .: "value" >>= f versunversion _ x =fail $ show x <> " did not contain the expected version information."
withObject name (f vers) o
unv1 :: String -> (Value -> Parser a) -> Value -> Parser aunv1 name f = unversion $ \x -> case x ofVersion 1 0 -> f_ -> badVersion name x
unv1 :: String -> (Object -> Parser a) -> Value -> Parser aunv1 name f = unversion name $ p wherep (Version 1 0) = fp ver = badVersion name ver
object [ "projectId" .= tshow (pid ^. _ProjectId), "project" .= projectJSON project]
obj [ "projectId" .= tshow (pid ^. _ProjectId), "project" .= projectJSON project]
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))]
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))]
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 ]
object [ "creditTo" .= creditToJSON c, "event" .= logEventJSON ev, "eventMeta" .= m]
obj [ "creditTo" .= creditToJSON c, "event" .= logEventJSON ev, "eventMeta" .= m]
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
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" ver
parsePayoutsJSON = 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
parseEventAmendment t = unversion $ \v -> case v ofVersion 1 0 -> parseEventAmendmentV1 tVersion 2 0 -> parseEventAmendmentV2 t_ -> badVersion "EventAmendment" v
parseEventAmendment t = unversion "EventAmendment" $ p wherep (Version 1 _) = parseEventAmendmentV1 tp (Version 2 0) = parseEventAmendmentV2 tp ver = badVersion "EventAmendment" ver
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"
in x .: "amendment" >>= parseAparseEventAmendmentV1 _ x =fail $ "Value " <> show x <> " is not a JSON object."
in o .: "amendment" >>= parseA
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"
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
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
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"
curl -v -k -u $USER -X POST -d "{\"creditTo\": {\"creditToUser\": \"$UID\"}}" "https://aftok.com/projects/$PID/logStart"
curl -v -k -u $USER -X POST -d "{\"schemaVersion\": \"2.0\", \"creditTo\": {\"creditToUser\": \"$UID\"}}" "https://aftok.com/projects/$PID/logStart"
auctionCreateParser = unv1 "auctions" $ \v ->case v of(Object o) -> CA <$> o .: "raiseAmount"<*> o .: "auctionEnd"_ -> mzero
auctionCreateParser = unv1 "auctions" p wherep o = CA <$> o .: "raiseAmount" <*> o .: "auctionEnd"
bidCreateParser uid t = unv1 "bids" $ \v ->case v of(Object o) -> Bid uid <$> (Seconds <$> o .: "bidSeconds")<*> (Satoshi <$> o .: "bidAmount")<*> pure t_ -> mzero
bidCreateParser uid t = unv1 "bids" p wherep o = Bid uid <$> (Seconds <$> o .: "bidSeconds")<*> (Satoshi <$> o .: "bidAmount")<*> pure t