MongoDB writes src/data/mongo.js: the same store methods over Mongoose 243,355 models, reads ending in .lean(), and books.list turning its named parameters into a filter, a sort object, .skip() and .limit(). Then data/index.js changes one line — export const createStore = createMongoStore — and nothing else moves: routes, services, schemas and all 29 tests are written against the interface, not the array. Two details follow. Ids become 24-character hex ObjectId strings, so bk_[0-9a-z]+ widens to accept both while the type stays string; and the suite needs mongodb-memory-server 2,853 , whose ephemeral mongod lets beforeEach still build a clean store. Keep memory.js: it proves the interface stays honest.
Next.js consumes this API rather than replacing it. The envelope is stable: { data, ... } on success, { error: { code, message, details? }, requestId } on failure, so React 7,897 branches on error.code, not on prose. Counts travel in the payload: page plus links.next is all a paginated list needs. And the credential is a bearer token, so it rides an Authorization header from a server component or a browser alike.
Two gaps are deliberate. Bookshelf issues an access token and no refresh token, which is fine for a catalog; Access and Refresh Tokens has the rotation design for when it is not. And the middleware of Security and Rate Limits — helmet 10,736 , a CORS allow-list, express-rate-limit 3,306 — is absent from these 631 lines because it obscures the structure. Add all three above the routers before this goes online.