@@ -14,6 +14,7 @@ import code.api.util.http4s.{ErrorResponseConverter, Http4sRequestAttributes, Id
1414import code .api .util .http4s .Http4sRequestAttributes .{EndpointHelpers , RequestOps }
1515import code .api .util .newstyle .ViewNewStyle
1616import code .api .v1_4_0 .JSONFactory1_4_0
17+ import code .api .v2_0_0 .AccountsHelper .accountTypeFilterText
1718import code .api .v2_0_0 .{BasicViewJson , CreateEntitlementJSON , JSONFactory200 }
1819import code .api .v4_0_0 .JSONFactory400
1920import code .api .v6_0_0 .{BasicAccountJsonV600 , BasicAccountsJsonV600 , BankJsonV600 , CacheConfigJsonV600 , CacheInfoJsonV600 , CacheNamespaceInfoJsonV600 , CacheNamespaceJsonV600 , CacheNamespacesJsonV600 , ConnectorInfoJsonV600 , ConnectorsJsonV600 , DatabasePoolInfoJsonV600 , FeaturesJsonV600 , InMemoryCacheStatusJsonV600 , JSONFactory600 , RedisCacheStatusJsonV600 , StoredProcedureConnectorHealthJsonV600 , UserV600 }
@@ -33,7 +34,7 @@ import code.metadata.tags.Tags
3334import code .views .Views
3435import code .accountattribute .AccountAttributeX
3536import code .users .{Users => UserVend }
36- import com .openbankproject .commons .model .{AccountId , BankId , BankIdAccountId , CounterpartyId , CustomerId , ListResult , TransactionRequestType , ViewId }
37+ import com .openbankproject .commons .model .{AccountId , BankId , BankIdAccountId , CoreAccount , CounterpartyId , CustomerId , ListResult , TransactionRequestType , ViewId }
3738import com .openbankproject .commons .model .enums .ChallengeType
3839import com .github .dwickern .macros .NameOf .nameOf
3940import com .openbankproject .commons .ExecutionContext .Implicits .global
@@ -344,6 +345,62 @@ object Http4s700 {
344345 http4sPartialFunction = Some (getCoreAccountById)
345346 )
346347
348+ // ─── corePrivateAccountsAllBanks (v7) ─────────────────────────────────────
349+ // Same semantics as v3.0.0 /my/accounts but with renamed fields so callers
350+ // can read the (bank_id, account_id, view_id) tuple without remapping.
351+ // v3: { id, ..., views: [ { id, ... } ] }
352+ // v7: { account_id, ..., views: [ { view_id, ... } ] }
353+
354+ val corePrivateAccountsAllBanks : HttpRoutes [IO ] = HttpRoutes .of[IO ] {
355+ case req @ GET -> `prefixPath` / " my" / " accounts" =>
356+ EndpointHelpers .withUser(req) { (user, cc) =>
357+ for {
358+ availablePrivateAccounts <- Views .views.vend.getPrivateBankAccountsFuture(user)
359+ (coreAccounts, _) <- NewStyle .function.getCoreBankAccountsFuture(availablePrivateAccounts, Some (cc))
360+ filtered = filterCoreAccountsByType(coreAccounts, req)
361+ } yield JSONFactory700 .createCoreAccountsByCoreAccountsJsonV700(filtered, user)
362+ }
363+ }
364+
365+ resourceDocs += ResourceDoc (
366+ null ,
367+ implementedInApiVersion,
368+ nameOf(corePrivateAccountsAllBanks),
369+ " GET" ,
370+ " /my/accounts" ,
371+ " Get Accounts at all Banks (private)" ,
372+ s """ Returns the list of accounts containing private views for the user.
373+ |Each account lists the views available to the user.
374+ |
375+ |This endpoint is the v7.0.0 version of `/obp/v3.0.0/my/accounts` with
376+ |renamed identifier fields: `account_id` (was `id`) and `view_id` (was `id` on each view)
377+ |so the response gives the `(bank_id, account_id, view_id)` tuple directly.
378+ |
379+ | ${accountTypeFilterText(" /my/accounts" )}
380+ |
381+ | ${userAuthenticationMessage(true )}
382+ | """ ,
383+ EmptyBody ,
384+ JSONFactory700 .coreAccountsJsonV700Example,
385+ List ($AuthenticatedUserIsRequired , UnknownError ),
386+ List (apiTagAccount, apiTagPSD2AIS, apiTagPrivateData, apiTagPsd2),
387+ None ,
388+ http4sPartialFunction = Some (corePrivateAccountsAllBanks)
389+ )
390+
391+ private def filterCoreAccountsByType (accounts : List [CoreAccount ], req : Request [IO ]): List [CoreAccount ] = {
392+ val qp = req.uri.query.multiParams
393+ val filters = qp.get(" account_type_filter" ).toList.flatMap(_.flatMap(_.split(" ," ))).filter(_.nonEmpty)
394+ val filtersOperation = qp.get(" account_type_filter_operation" ).flatMap(_.headOption).getOrElse(" INCLUDE" )
395+ accounts.filter { account =>
396+ (filters, filtersOperation) match {
397+ case (f, " INCLUDE" ) if f.nonEmpty => f.contains(account.accountType)
398+ case (f, " EXCLUDE" ) if f.nonEmpty => ! f.contains(account.accountType)
399+ case _ => true
400+ }
401+ }
402+ }
403+
347404 // Category: withView (user + account + view resolved from BANK_ID + ACCOUNT_ID + VIEW_ID by middleware)
348405 val getPrivateAccountByIdFull : HttpRoutes [IO ] = HttpRoutes .of[IO ] {
349406 case req @ GET -> `prefixPath` / " banks" / _ / " accounts" / _ / viewIdStr / " account" =>
0 commit comments