[{"data":1,"prerenderedAt":1449},["ShallowReactive",2],{"navigation":3,"\u002Fbooki-documentation\u002Fguides\u002Fguides-redis":303,"\u002Fbooki-documentation\u002Fguides\u002Fguides-redis-surround":1444},[4,55,105],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":54},"Nuxt Guide","i-lucide-layout","\u002Fnuxt-guide","1.nuxt-guide",[10,14,19,24,29,34,39,44,49],{"title":11,"path":12,"stem":13,"icon":6},"Overview","\u002Fnuxt-guide\u002Foverview","1.nuxt-guide\u002F1.overview",{"title":15,"path":16,"stem":17,"icon":18},"Folder Structure","\u002Fnuxt-guide\u002Ffolder-structure","1.nuxt-guide\u002F2.folder-structure","i-lucide-folder-tree",{"title":20,"path":21,"stem":22,"icon":23},"Components","\u002Fnuxt-guide\u002Fcomponents","1.nuxt-guide\u002F3.components","i-lucide-component",{"title":25,"path":26,"stem":27,"icon":28},"Composables","\u002Fnuxt-guide\u002Fcomposables","1.nuxt-guide\u002F4.composables","i-lucide-puzzle",{"title":30,"path":31,"stem":32,"icon":33},"Pages & Routing","\u002Fnuxt-guide\u002Fpages-routing","1.nuxt-guide\u002F5.pages-routing","i-lucide-file-text",{"title":35,"path":36,"stem":37,"icon":38},"Middleware","\u002Fnuxt-guide\u002Fmiddleware","1.nuxt-guide\u002F6.middleware","i-lucide-shield-check",{"title":40,"path":41,"stem":42,"icon":43},"Plugins","\u002Fnuxt-guide\u002Fplugins","1.nuxt-guide\u002F7.plugins","i-lucide-plug",{"title":45,"path":46,"stem":47,"icon":48},"State Management","\u002Fnuxt-guide\u002Fstate-management","1.nuxt-guide\u002F8.state-management","i-lucide-database",{"title":50,"path":51,"stem":52,"icon":53},"TypeScript","\u002Fnuxt-guide\u002Ftypescript","1.nuxt-guide\u002F9.typescript","i-lucide-braces",false,{"title":56,"icon":57,"path":58,"stem":59,"children":60,"page":54},"Node \u002F Express Guide","i-lucide-server","\u002Fnode-express-guide","2.node-express-guide",[61,64,69,72,77,82,86,91,96,100],{"title":11,"path":62,"stem":63,"icon":57},"\u002Fnode-express-guide\u002Foverview","2.node-express-guide\u002F1.overview",{"title":65,"path":66,"stem":67,"icon":68},"Error Handling","\u002Fnode-express-guide\u002Ferror-handling","2.node-express-guide\u002F10.error-handling","i-lucide-alert-triangle",{"title":15,"path":70,"stem":71,"icon":18},"\u002Fnode-express-guide\u002Ffolder-structure","2.node-express-guide\u002F2.folder-structure",{"title":73,"path":74,"stem":75,"icon":76},"Controllers","\u002Fnode-express-guide\u002Fcontrollers","2.node-express-guide\u002F3.controllers","i-lucide-cpu",{"title":78,"path":79,"stem":80,"icon":81},"Services","\u002Fnode-express-guide\u002Fservices","2.node-express-guide\u002F4.services","i-lucide-workflow",{"title":83,"path":84,"stem":85,"icon":48},"Repositories","\u002Fnode-express-guide\u002Frepositories","2.node-express-guide\u002F5.repositories",{"title":87,"path":88,"stem":89,"icon":90},"Models","\u002Fnode-express-guide\u002Fmodels","2.node-express-guide\u002F6.models","i-lucide-boxes",{"title":92,"path":93,"stem":94,"icon":95},"Routes","\u002Fnode-express-guide\u002Froutes","2.node-express-guide\u002F7.routes","i-lucide-route",{"title":35,"path":97,"stem":98,"icon":99},"\u002Fnode-express-guide\u002Fmiddleware","2.node-express-guide\u002F8.middleware","i-lucide-shield",{"title":101,"path":102,"stem":103,"icon":104},"Validation","\u002Fnode-express-guide\u002Fvalidation","2.node-express-guide\u002F9.validation","i-lucide-check-circle",{"title":106,"icon":107,"path":108,"stem":109,"children":110,"page":54},"Booki Documentation","i-lucide-book-open","\u002Fbooki-documentation","3.booki-documentation",[111,115,120,125,130,229,244,257],{"title":112,"path":113,"stem":114,"icon":107},"Project Overview","\u002Fbooki-documentation\u002Foverview","3.booki-documentation\u002F1.overview",{"title":116,"path":117,"stem":118,"icon":119},"Installation","\u002Fbooki-documentation\u002F1.installation","3.booki-documentation\u002F2.1.installation","i-lucide-download",{"title":121,"path":122,"stem":123,"icon":124},"Development Overview","\u002Fbooki-documentation\u002F2.architecture","3.booki-documentation\u002F2.2.architecture","i-lucide-layers",{"title":126,"path":127,"stem":128,"icon":129},"Local Development","\u002Fbooki-documentation\u002F3.local-development","3.booki-documentation\u002F2.3.local-development","i-lucide-monitor",{"title":131,"icon":57,"path":132,"stem":133,"children":134,"page":54},"API","\u002Fbooki-documentation\u002Fapi","3.booki-documentation\u002F3.api",[135,139,144,149,154,159,163,168,173,178,183,188,192,197,202,206,211,216,220,224],{"title":136,"path":137,"stem":138,"icon":57},"Booki API Reference","\u002Fbooki-documentation\u002Fapi\u002Fbooki-api","3.booki-documentation\u002F3.api\u002F1.booki-api",{"title":140,"path":141,"stem":142,"icon":143},"Auth - Login & Refresh","\u002Fbooki-documentation\u002Fapi\u002Fauth","3.booki-documentation\u002F3.api\u002F2.auth","i-lucide-key",{"title":145,"path":146,"stem":147,"icon":148},"Auth - Customer Registration","\u002Fbooki-documentation\u002Fapi\u002Fauth-customer-register","3.booki-documentation\u002F3.api\u002F2.auth-customer-register","i-lucide-user-check",{"title":150,"path":151,"stem":152,"icon":153},"Auth - Owner Registration","\u002Fbooki-documentation\u002Fapi\u002Fauth-owner-register","3.booki-documentation\u002F3.api\u002F2.auth-owner-register","i-lucide-user-plus",{"title":155,"path":156,"stem":157,"icon":158},"Bookings","\u002Fbooki-documentation\u002Fapi\u002Fbookings","3.booki-documentation\u002F3.api\u002F3.bookings","i-lucide-calendar-check",{"title":160,"path":161,"stem":162,"icon":158},"Bookings - Authenticated","\u002Fbooki-documentation\u002Fapi\u002Fbookings-auth","3.booki-documentation\u002F3.api\u002F3.bookings-auth",{"title":164,"path":165,"stem":166,"icon":167},"Bookings - Public & Guest","\u002Fbooki-documentation\u002Fapi\u002Fbookings-public","3.booki-documentation\u002F3.api\u002F3.bookings-public","i-lucide-calendar-plus",{"title":169,"path":170,"stem":171,"icon":172},"Booking Services","\u002Fbooki-documentation\u002Fapi\u002Fbooking-services","3.booki-documentation\u002F3.api\u002F4.booking-services","i-lucide-box",{"title":174,"path":175,"stem":176,"icon":177},"Organizations - Branches","\u002Fbooki-documentation\u002Fapi\u002Fbranches","3.booki-documentation\u002F3.api\u002F5.branches","i-lucide-git-branch",{"title":179,"path":180,"stem":181,"icon":182},"Organizations - Business Hours","\u002Fbooki-documentation\u002Fapi\u002Fbusiness-hours","3.booki-documentation\u002F3.api\u002F5.business-hours","i-lucide-clock",{"title":184,"path":185,"stem":186,"icon":187},"Organizations - Base","\u002Fbooki-documentation\u002Fapi\u002Forganizations","3.booki-documentation\u002F3.api\u002F5.organizations","i-lucide-building-2",{"title":189,"path":190,"stem":191,"icon":172},"Organizations - Packages","\u002Fbooki-documentation\u002Fapi\u002Fpackages","3.booki-documentation\u002F3.api\u002F5.packages",{"title":193,"path":194,"stem":195,"icon":196},"Organizations - Payments & Integrations","\u002Fbooki-documentation\u002Fapi\u002Fpayments","3.booki-documentation\u002F3.api\u002F5.payments","i-lucide-credit-card",{"title":198,"path":199,"stem":200,"icon":201},"Users - Profile & Settings","\u002Fbooki-documentation\u002Fapi\u002Fusers","3.booki-documentation\u002F3.api\u002F6.users","i-lucide-user",{"title":203,"path":204,"stem":205,"icon":196},"Maya Payments","\u002Fbooki-documentation\u002Fapi\u002Fmaya","3.booki-documentation\u002F3.api\u002F7.maya",{"title":207,"path":208,"stem":209,"icon":210},"Owner - Booking Management","\u002Fbooki-documentation\u002Fapi\u002Fowner-bookings","3.booki-documentation\u002F3.api\u002F7.owner-bookings","i-lucide-calendar",{"title":212,"path":213,"stem":214,"icon":215},"Owner - Customer Management","\u002Fbooki-documentation\u002Fapi\u002Fowner-customers","3.booki-documentation\u002F3.api\u002F7.owner-customers","i-lucide-users",{"title":217,"path":218,"stem":219,"icon":196},"Admin - Billing & Subscriptions","\u002Fbooki-documentation\u002Fapi\u002Fadmin-billing","3.booki-documentation\u002F3.api\u002F8.admin-billing",{"title":221,"path":222,"stem":223,"icon":187},"Admin - Organizations Management","\u002Fbooki-documentation\u002Fapi\u002Fadmin-organizations","3.booki-documentation\u002F3.api\u002F8.admin-organizations",{"title":225,"path":226,"stem":227,"icon":228},"Admin - User Management","\u002Fbooki-documentation\u002Fapi\u002Fadmin-users","3.booki-documentation\u002F3.api\u002F8.admin-users","i-lucide-shield-admin",{"title":230,"icon":231,"path":232,"stem":233,"children":234,"page":54},"Shared","i-lucide-package","\u002Fbooki-documentation\u002Fshared","3.booki-documentation\u002F4.shared",[235,240],{"title":236,"path":237,"stem":238,"icon":239},"codi-node-utils","\u002Fbooki-documentation\u002Fshared\u002Fcodi-node-utils","3.booki-documentation\u002F4.shared\u002F1.codi-node-utils","i-lucide-wrench",{"title":241,"path":242,"stem":243,"icon":124},"codi-layer","\u002Fbooki-documentation\u002Fshared\u002Fcodi-layer","3.booki-documentation\u002F4.shared\u002F2.codi-layer",{"title":245,"path":246,"stem":247,"children":248,"page":54},"Flowcharts","\u002Fbooki-documentation\u002Fflowcharts","3.booki-documentation\u002F5.flowcharts",[249,253],{"title":250,"path":251,"stem":252,"icon":158},"Owner Booking Management Flow","\u002Fbooki-documentation\u002Fflowcharts\u002Fowner-booking-management","3.booki-documentation\u002F5.flowcharts\u002F1.owner-booking-management",{"title":254,"path":255,"stem":256,"icon":167},"Customer Booking Flow","\u002Fbooki-documentation\u002Fflowcharts\u002Fcustomer-booking-flow","3.booki-documentation\u002F5.flowcharts\u002F2.customer-booking-flow",{"title":258,"path":259,"stem":260,"children":261,"page":54},"Guides","\u002Fbooki-documentation\u002Fguides","3.booki-documentation\u002Fguides",[262,267,271,275,280,285,290,294,298],{"title":263,"path":264,"stem":265,"icon":266},"Guide - Authentication Flow & Sessions","\u002Fbooki-documentation\u002Fguides\u002Fguides-auth-flow","3.booki-documentation\u002Fguides\u002Fguides-auth-flow","i-lucide-lock",{"title":268,"path":269,"stem":270,"icon":177},"Guide - Branch Management","\u002Fbooki-documentation\u002Fguides\u002Fguides-branch-management","3.booki-documentation\u002Fguides\u002Fguides-branch-management",{"title":272,"path":273,"stem":274,"icon":196},"Guide - Customer Payment Methods","\u002Fbooki-documentation\u002Fguides\u002Fguides-customer-payments","3.booki-documentation\u002Fguides\u002Fguides-customer-payments",{"title":276,"path":277,"stem":278,"icon":279},"Guide - Environment Setup","\u002Fbooki-documentation\u002Fguides\u002Fguides-environment-setup","3.booki-documentation\u002Fguides\u002Fguides-environment-setup","i-lucide-settings",{"title":281,"path":282,"stem":283,"icon":284},"Guide - Common Error Responses","\u002Fbooki-documentation\u002Fguides\u002Fguides-errors","3.booki-documentation\u002Fguides\u002Fguides-errors","i-lucide-alert-circle",{"title":286,"path":287,"stem":288,"icon":289},"Guide - Gmail SMTP Setup","\u002Fbooki-documentation\u002Fguides\u002Fguides-gmail-setup","3.booki-documentation\u002Fguides\u002Fguides-gmail-setup","i-lucide-mail",{"title":291,"path":292,"stem":293,"icon":124},"Guide - Multi-Tenancy & Tenant Slug Resolution","\u002Fbooki-documentation\u002Fguides\u002Fguides-multi-tenancy","3.booki-documentation\u002Fguides\u002Fguides-multi-tenancy",{"title":295,"path":296,"stem":297,"icon":48},"Guide - Redis Caching","\u002Fbooki-documentation\u002Fguides\u002Fguides-redis","3.booki-documentation\u002Fguides\u002Fguides-redis",{"title":299,"path":300,"stem":301,"icon":302},"Guide - Subscription Billing","\u002Fbooki-documentation\u002Fguides\u002Fguides-subscription-billing","3.booki-documentation\u002Fguides\u002Fguides-subscription-billing","i-lucide-receipt",{"id":304,"title":295,"body":305,"description":1437,"extension":1438,"links":1439,"meta":1440,"navigation":1441,"path":296,"seo":1442,"stem":297,"__hash__":1443},"docs\u002F3.booki-documentation\u002Fguides\u002Fguides-redis.md",{"type":306,"value":307,"toc":1418},"minimark",[308,316,319,324,329,354,389,393,409,432,436,526,550,552,556,648,650,654,661,803,806,814,850,852,856,959,969,971,975,978,1028,1032,1102,1106,1202,1206,1235,1239,1275,1277,1281,1376,1380,1414],[309,310,311,315],"p",{},[312,313,314],"code",{},"booki-api"," uses Redis to cache frequently-read data (organizations, packages, branches, users) and reduce MongoDB round-trips. This guide covers installation, configuration, cache key patterns, and day-to-day CLI commands.",[317,318],"hr",{},[320,321,323],"h2",{"id":322},"setup","Setup",[325,326,328],"h3",{"id":327},"option-a-redis-cloud-recommended","Option A — Redis Cloud (recommended)",[330,331,332,344,347],"ol",{},[333,334,335,336,343],"li",{},"Sign up at ",[337,338,342],"a",{"href":339,"rel":340},"https:\u002F\u002Fredis.com\u002Ftry-free\u002F",[341],"nofollow","redis.com\u002Ftry-free"," — free 30 MB tier is enough for development.",[333,345,346],{},"Create a database.",[333,348,349,350,353],{},"Copy host, port, and password into ",[312,351,352],{},".env",":",[355,356,361],"pre",{"className":357,"code":358,"language":359,"meta":360,"style":360},"language-env shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","REDIS_HOST=redis-12345.c1.us-east-1-2.ec2.cloud.redislabs.com\nREDIS_PORT=12345\nREDIS_PASSWORD=your-password\nREDIS_TLS=true\n","env","",[312,362,363,371,377,383],{"__ignoreMap":360},[364,365,368],"span",{"class":366,"line":367},"line",1,[364,369,370],{},"REDIS_HOST=redis-12345.c1.us-east-1-2.ec2.cloud.redislabs.com\n",[364,372,374],{"class":366,"line":373},2,[364,375,376],{},"REDIS_PORT=12345\n",[364,378,380],{"class":366,"line":379},3,[364,381,382],{},"REDIS_PASSWORD=your-password\n",[364,384,386],{"class":366,"line":385},4,[364,387,388],{},"REDIS_TLS=true\n",[325,390,392],{"id":391},"option-b-upstash-serverless-pay-per-request","Option B — Upstash (serverless, pay-per-request)",[330,394,395,403,406],{},[333,396,335,397,402],{},[337,398,401],{"href":399,"rel":400},"https:\u002F\u002Fupstash.com\u002F",[341],"upstash.com",".",[333,404,405],{},"Create a Redis database.",[333,407,408],{},"Copy the REST endpoint credentials — Upstash requires TLS:",[355,410,412],{"className":357,"code":411,"language":359,"meta":360,"style":360},"REDIS_HOST=us1-your-db.upstash.io\nREDIS_PORT=6379\nREDIS_PASSWORD=your-password\nREDIS_TLS=true\n",[312,413,414,419,424,428],{"__ignoreMap":360},[364,415,416],{"class":366,"line":367},[364,417,418],{},"REDIS_HOST=us1-your-db.upstash.io\n",[364,420,421],{"class":366,"line":373},[364,422,423],{},"REDIS_PORT=6379\n",[364,425,426],{"class":366,"line":379},[364,427,382],{},[364,429,430],{"class":366,"line":385},[364,431,388],{},[325,433,435],{"id":434},"option-c-local-redis","Option C — Local Redis",[355,437,441],{"className":438,"code":439,"language":440,"meta":360,"style":360},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# macOS\nbrew install redis && brew services start redis\n\n# Linux\nsudo apt-get install redis-server && sudo systemctl start redis\n\n# Windows — download from https:\u002F\u002Fgithub.com\u002Fmicrosoftarchive\u002Fredis\u002Freleases\n","bash",[312,442,443,449,478,484,489,515,520],{"__ignoreMap":360},[364,444,445],{"class":366,"line":367},[364,446,448],{"class":447},"sHwdD","# macOS\n",[364,450,451,455,459,462,466,469,472,475],{"class":366,"line":373},[364,452,454],{"class":453},"sBMFI","brew",[364,456,458],{"class":457},"sfazB"," install",[364,460,461],{"class":457}," redis",[364,463,465],{"class":464},"sMK4o"," &&",[364,467,468],{"class":453}," brew",[364,470,471],{"class":457}," services",[364,473,474],{"class":457}," start",[364,476,477],{"class":457}," redis\n",[364,479,480],{"class":366,"line":379},[364,481,483],{"emptyLinePlaceholder":482},true,"\n",[364,485,486],{"class":366,"line":385},[364,487,488],{"class":447},"# Linux\n",[364,490,492,495,498,500,503,505,508,511,513],{"class":366,"line":491},5,[364,493,494],{"class":453},"sudo",[364,496,497],{"class":457}," apt-get",[364,499,458],{"class":457},[364,501,502],{"class":457}," redis-server",[364,504,465],{"class":464},[364,506,507],{"class":453}," sudo",[364,509,510],{"class":457}," systemctl",[364,512,474],{"class":457},[364,514,477],{"class":457},[364,516,518],{"class":366,"line":517},6,[364,519,483],{"emptyLinePlaceholder":482},[364,521,523],{"class":366,"line":522},7,[364,524,525],{"class":447},"# Windows — download from https:\u002F\u002Fgithub.com\u002Fmicrosoftarchive\u002Fredis\u002Freleases\n",[355,527,529],{"className":357,"code":528,"language":359,"meta":360,"style":360},"REDIS_HOST=localhost\nREDIS_PORT=6379\nREDIS_PASSWORD=\nREDIS_TLS=false\n",[312,530,531,536,540,545],{"__ignoreMap":360},[364,532,533],{"class":366,"line":367},[364,534,535],{},"REDIS_HOST=localhost\n",[364,537,538],{"class":366,"line":373},[364,539,423],{},[364,541,542],{"class":366,"line":379},[364,543,544],{},"REDIS_PASSWORD=\n",[364,546,547],{"class":366,"line":385},[364,548,549],{},"REDIS_TLS=false\n",[317,551],{},[320,553,555],{"id":554},"environment-variables","Environment Variables",[557,558,559,578],"table",{},[560,561,562],"thead",{},[563,564,565,569,572,575],"tr",{},[566,567,568],"th",{},"Variable",[566,570,571],{},"Required",[566,573,574],{},"Default",[566,576,577],{},"Description",[579,580,581,598,612,627],"tbody",{},[563,582,583,589,592,595],{},[584,585,586],"td",{},[312,587,588],{},"REDIS_HOST",[584,590,591],{},"Yes",[584,593,594],{},"—",[584,596,597],{},"Redis server hostname",[563,599,600,605,607,609],{},[584,601,602],{},[312,603,604],{},"REDIS_PORT",[584,606,591],{},[584,608,594],{},[584,610,611],{},"Redis server port",[563,613,614,619,622,624],{},[584,615,616],{},[312,617,618],{},"REDIS_PASSWORD",[584,620,621],{},"Cloud only",[584,623,594],{},[584,625,626],{},"Auth password (leave empty for local)",[563,628,629,634,636,641],{},[584,630,631],{},[312,632,633],{},"REDIS_TLS",[584,635,621],{},[584,637,638],{},[312,639,640],{},"false",[584,642,643,644,647],{},"Set ",[312,645,646],{},"true"," for Redis Cloud \u002F Upstash",[317,649],{},[320,651,653],{"id":652},"how-caching-works-in-booki-api","How Caching Works in booki-api",[309,655,656,657,660],{},"The caching layer sits in repositories. Each repo method optionally passes a ",[312,658,659],{},"cacheOptions"," object to the base repository:",[355,662,666],{"className":663,"code":664,"language":665,"meta":360,"style":360},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Cache for 10 minutes with a descriptive key\nconst cacheOptions = { ttl: 600, key: `org:${id}` };\nconst org = await base.getById(\n  id,\n  pipeline,\n  true,\n  cacheOptions,\n  \"organization\",\n);\n","typescript",[312,667,668,673,725,750,758,765,773,780,794],{"__ignoreMap":360},[364,669,670],{"class":366,"line":367},[364,671,672],{"class":447},"\u002F\u002F Cache for 10 minutes with a descriptive key\n",[364,674,675,679,683,686,689,693,695,699,702,705,707,710,713,716,719,722],{"class":366,"line":373},[364,676,678],{"class":677},"spNyl","const",[364,680,682],{"class":681},"sTEyZ"," cacheOptions ",[364,684,685],{"class":464},"=",[364,687,688],{"class":464}," {",[364,690,692],{"class":691},"swJcz"," ttl",[364,694,353],{"class":464},[364,696,698],{"class":697},"sbssI"," 600",[364,700,701],{"class":464},",",[364,703,704],{"class":691}," key",[364,706,353],{"class":464},[364,708,709],{"class":464}," `",[364,711,712],{"class":457},"org:",[364,714,715],{"class":464},"${",[364,717,718],{"class":681},"id",[364,720,721],{"class":464},"}`",[364,723,724],{"class":464}," };\n",[364,726,727,729,732,734,738,741,743,747],{"class":366,"line":379},[364,728,678],{"class":677},[364,730,731],{"class":681}," org ",[364,733,685],{"class":464},[364,735,737],{"class":736},"s7zQu"," await",[364,739,740],{"class":681}," base",[364,742,402],{"class":464},[364,744,746],{"class":745},"s2Zo4","getById",[364,748,749],{"class":681},"(\n",[364,751,752,755],{"class":366,"line":385},[364,753,754],{"class":681},"  id",[364,756,757],{"class":464},",\n",[364,759,760,763],{"class":366,"line":491},[364,761,762],{"class":681},"  pipeline",[364,764,757],{"class":464},[364,766,767,771],{"class":366,"line":517},[364,768,770],{"class":769},"sfNiH","  true",[364,772,757],{"class":464},[364,774,775,778],{"class":366,"line":522},[364,776,777],{"class":681},"  cacheOptions",[364,779,757],{"class":464},[364,781,783,786,789,792],{"class":366,"line":782},8,[364,784,785],{"class":464},"  \"",[364,787,788],{"class":457},"organization",[364,790,791],{"class":464},"\"",[364,793,757],{"class":464},[364,795,797,800],{"class":366,"line":796},9,[364,798,799],{"class":681},")",[364,801,802],{"class":464},";\n",[309,804,805],{},"On cache hit, MongoDB is bypassed entirely. On cache miss, the query runs and the result is stored.",[309,807,808,809,813],{},"Cache is ",[810,811,812],"strong",{},"invalidated"," by the service layer on write operations (create \u002F update \u002F delete):",[355,815,817],{"className":663,"code":816,"language":665,"meta":360,"style":360},"await cache.del(`org:${id}`);\n",[312,818,819],{"__ignoreMap":360},[364,820,821,824,827,829,832,835,838,840,842,844,846,848],{"class":366,"line":367},[364,822,823],{"class":736},"await",[364,825,826],{"class":681}," cache",[364,828,402],{"class":464},[364,830,831],{"class":745},"del",[364,833,834],{"class":681},"(",[364,836,837],{"class":464},"`",[364,839,712],{"class":457},[364,841,715],{"class":464},[364,843,718],{"class":681},[364,845,721],{"class":464},[364,847,799],{"class":681},[364,849,802],{"class":464},[317,851],{},[320,853,855],{"id":854},"cache-key-patterns","Cache Key Patterns",[557,857,858,871],{},[560,859,860],{},[563,861,862,865,868],{},[566,863,864],{},"Key Pattern",[566,866,867],{},"What It Caches",[566,869,870],{},"TTL",[579,872,873,886,898,910,922,934,946],{},[563,874,875,880,883],{},[584,876,877],{},[312,878,879],{},"org:{organizationId}",[584,881,882],{},"Organization document",[584,884,885],{},"10 min",[563,887,888,893,896],{},[584,889,890],{},[312,891,892],{},"branch:{branchId}",[584,894,895],{},"Branch document",[584,897,885],{},[563,899,900,905,908],{},[584,901,902],{},[312,903,904],{},"branch:slug:{slug}:{organizationId}",[584,906,907],{},"Branch by slug scoped to org",[584,909,885],{},[563,911,912,917,920],{},[584,913,914],{},[312,915,916],{},"package:{packageId}",[584,918,919],{},"Service package",[584,921,885],{},[563,923,924,929,932],{},[584,925,926],{},[312,927,928],{},"packages:org:{organizationId}",[584,930,931],{},"All packages for an org",[584,933,885],{},[563,935,936,941,944],{},[584,937,938],{},[312,939,940],{},"user:{userId}",[584,942,943],{},"User profile",[584,945,885],{},[563,947,948,953,956],{},[584,949,950],{},[312,951,952],{},"tenant:slug:{slug}",[584,954,955],{},"Org ID resolved from slug",[584,957,958],{},"5 min",[960,961,962],"blockquote",{},[309,963,964,965,968],{},"Keys are always scoped by ",[312,966,967],{},"organizationId"," where applicable to prevent cross-tenant cache collisions.",[317,970],{},[320,972,974],{"id":973},"common-cli-commands","Common CLI Commands",[309,976,977],{},"Connect to your Redis instance:",[355,979,981],{"className":438,"code":980,"language":440,"meta":360,"style":360},"# Local\nredis-cli\n\n# Redis Cloud \u002F remote (with TLS)\nredis-cli -h YOUR_HOST -p YOUR_PORT -a YOUR_PASSWORD --tls\n",[312,982,983,988,993,997,1002],{"__ignoreMap":360},[364,984,985],{"class":366,"line":367},[364,986,987],{"class":447},"# Local\n",[364,989,990],{"class":366,"line":373},[364,991,992],{"class":453},"redis-cli\n",[364,994,995],{"class":366,"line":379},[364,996,483],{"emptyLinePlaceholder":482},[364,998,999],{"class":366,"line":385},[364,1000,1001],{"class":447},"# Redis Cloud \u002F remote (with TLS)\n",[364,1003,1004,1007,1010,1013,1016,1019,1022,1025],{"class":366,"line":491},[364,1005,1006],{"class":453},"redis-cli",[364,1008,1009],{"class":457}," -h",[364,1011,1012],{"class":457}," YOUR_HOST",[364,1014,1015],{"class":457}," -p",[364,1017,1018],{"class":457}," YOUR_PORT",[364,1020,1021],{"class":457}," -a",[364,1023,1024],{"class":457}," YOUR_PASSWORD",[364,1026,1027],{"class":457}," --tls\n",[325,1029,1031],{"id":1030},"inspect-keys","Inspect keys",[355,1033,1035],{"className":438,"code":1034,"language":440,"meta":360,"style":360},"# List all booki-api keys\nKEYS org:*\nKEYS branch:*\nKEYS user:*\n\n# Scan (safer on large datasets — non-blocking)\nSCAN 0 MATCH org:* COUNT 100\n",[312,1036,1037,1042,1053,1062,1071,1075,1080],{"__ignoreMap":360},[364,1038,1039],{"class":366,"line":367},[364,1040,1041],{"class":447},"# List all booki-api keys\n",[364,1043,1044,1047,1050],{"class":366,"line":373},[364,1045,1046],{"class":453},"KEYS",[364,1048,1049],{"class":457}," org:",[364,1051,1052],{"class":681},"*\n",[364,1054,1055,1057,1060],{"class":366,"line":379},[364,1056,1046],{"class":453},[364,1058,1059],{"class":457}," branch:",[364,1061,1052],{"class":681},[364,1063,1064,1066,1069],{"class":366,"line":385},[364,1065,1046],{"class":453},[364,1067,1068],{"class":457}," user:",[364,1070,1052],{"class":681},[364,1072,1073],{"class":366,"line":491},[364,1074,483],{"emptyLinePlaceholder":482},[364,1076,1077],{"class":366,"line":517},[364,1078,1079],{"class":447},"# Scan (safer on large datasets — non-blocking)\n",[364,1081,1082,1085,1088,1091,1093,1096,1099],{"class":366,"line":522},[364,1083,1084],{"class":453},"SCAN",[364,1086,1087],{"class":697}," 0",[364,1089,1090],{"class":457}," MATCH",[364,1092,1049],{"class":457},[364,1094,1095],{"class":681},"*",[364,1097,1098],{"class":457}," COUNT",[364,1100,1101],{"class":697}," 100\n",[325,1103,1105],{"id":1104},"read-and-delete","Read and delete",[355,1107,1109],{"className":438,"code":1108,"language":440,"meta":360,"style":360},"# Read a value\nGET org:507f191e810c19729de860ea\n\n# Check TTL (seconds remaining)\nTTL org:507f191e810c19729de860ea\n\n# Delete a single key\nDEL org:507f191e810c19729de860ea\n\n# Delete all keys matching a pattern (use with caution)\n# Redis \u003C 7: no UNLINK with pattern; use a pipeline\nredis-cli --scan --pattern \"org:*\" | xargs redis-cli DEL\n",[312,1110,1111,1116,1124,1128,1133,1139,1143,1148,1155,1159,1165,1171],{"__ignoreMap":360},[364,1112,1113],{"class":366,"line":367},[364,1114,1115],{"class":447},"# Read a value\n",[364,1117,1118,1121],{"class":366,"line":373},[364,1119,1120],{"class":453},"GET",[364,1122,1123],{"class":457}," org:507f191e810c19729de860ea\n",[364,1125,1126],{"class":366,"line":379},[364,1127,483],{"emptyLinePlaceholder":482},[364,1129,1130],{"class":366,"line":385},[364,1131,1132],{"class":447},"# Check TTL (seconds remaining)\n",[364,1134,1135,1137],{"class":366,"line":491},[364,1136,870],{"class":453},[364,1138,1123],{"class":457},[364,1140,1141],{"class":366,"line":517},[364,1142,483],{"emptyLinePlaceholder":482},[364,1144,1145],{"class":366,"line":522},[364,1146,1147],{"class":447},"# Delete a single key\n",[364,1149,1150,1153],{"class":366,"line":782},[364,1151,1152],{"class":453},"DEL",[364,1154,1123],{"class":457},[364,1156,1157],{"class":366,"line":796},[364,1158,483],{"emptyLinePlaceholder":482},[364,1160,1162],{"class":366,"line":1161},10,[364,1163,1164],{"class":447},"# Delete all keys matching a pattern (use with caution)\n",[364,1166,1168],{"class":366,"line":1167},11,[364,1169,1170],{"class":447},"# Redis \u003C 7: no UNLINK with pattern; use a pipeline\n",[364,1172,1174,1176,1179,1182,1185,1188,1190,1193,1196,1199],{"class":366,"line":1173},12,[364,1175,1006],{"class":453},[364,1177,1178],{"class":457}," --scan",[364,1180,1181],{"class":457}," --pattern",[364,1183,1184],{"class":464}," \"",[364,1186,1187],{"class":457},"org:*",[364,1189,791],{"class":464},[364,1191,1192],{"class":464}," |",[364,1194,1195],{"class":453}," xargs",[364,1197,1198],{"class":457}," redis-cli",[364,1200,1201],{"class":457}," DEL\n",[325,1203,1205],{"id":1204},"flush-development-only","Flush (development only)",[355,1207,1209],{"className":438,"code":1208,"language":440,"meta":360,"style":360},"# Clear ALL keys in current database — destructive, dev only\nFLUSHDB\n\n# Clear all databases — never use in production\nFLUSHALL\n",[312,1210,1211,1216,1221,1225,1230],{"__ignoreMap":360},[364,1212,1213],{"class":366,"line":367},[364,1214,1215],{"class":447},"# Clear ALL keys in current database — destructive, dev only\n",[364,1217,1218],{"class":366,"line":373},[364,1219,1220],{"class":453},"FLUSHDB\n",[364,1222,1223],{"class":366,"line":379},[364,1224,483],{"emptyLinePlaceholder":482},[364,1226,1227],{"class":366,"line":385},[364,1228,1229],{"class":447},"# Clear all databases — never use in production\n",[364,1231,1232],{"class":366,"line":491},[364,1233,1234],{"class":453},"FLUSHALL\n",[325,1236,1238],{"id":1237},"server-info","Server info",[355,1240,1242],{"className":438,"code":1241,"language":440,"meta":360,"style":360},"INFO memory        # Memory usage\nINFO stats         # Hit\u002Fmiss statistics\nINFO keyspace      # Key count per database\n",[312,1243,1244,1255,1265],{"__ignoreMap":360},[364,1245,1246,1249,1252],{"class":366,"line":367},[364,1247,1248],{"class":453},"INFO",[364,1250,1251],{"class":457}," memory",[364,1253,1254],{"class":447},"        # Memory usage\n",[364,1256,1257,1259,1262],{"class":366,"line":373},[364,1258,1248],{"class":453},[364,1260,1261],{"class":457}," stats",[364,1263,1264],{"class":447},"         # Hit\u002Fmiss statistics\n",[364,1266,1267,1269,1272],{"class":366,"line":379},[364,1268,1248],{"class":453},[364,1270,1271],{"class":457}," keyspace",[364,1273,1274],{"class":447},"      # Key count per database\n",[317,1276],{},[320,1278,1280],{"id":1279},"troubleshooting","Troubleshooting",[557,1282,1283,1296],{},[560,1284,1285],{},[563,1286,1287,1290,1293],{},[566,1288,1289],{},"Symptom",[566,1291,1292],{},"Likely Cause",[566,1294,1295],{},"Fix",[579,1297,1298,1314,1330,1346,1361],{},[563,1299,1300,1306,1309],{},[584,1301,1302,1305],{},[312,1303,1304],{},"ECONNREFUSED"," on startup",[584,1307,1308],{},"Redis not running",[584,1310,1311,1312],{},"Start Redis; check host\u002Fport in ",[312,1313,352],{},[563,1315,1316,1322,1327],{},[584,1317,1318,1321],{},[312,1319,1320],{},"WRONGPASS"," error",[584,1323,1324,1325],{},"Incorrect ",[312,1326,618],{},[584,1328,1329],{},"Double-check password in Redis dashboard",[563,1331,1332,1335,1341],{},[584,1333,1334],{},"TLS handshake errors",[584,1336,1337,1338],{},"Missing ",[312,1339,1340],{},"REDIS_TLS=true",[584,1342,643,1343,1345],{},[312,1344,1340],{}," for cloud instances",[563,1347,1348,1351,1354],{},[584,1349,1350],{},"Stale data after update",[584,1352,1353],{},"Cache not invalidated",[584,1355,1356,1357,1360],{},"Verify service layer calls ",[312,1358,1359],{},"cache.del(key)"," after writes",[563,1362,1363,1366,1369],{},[584,1364,1365],{},"High memory usage",[584,1367,1368],{},"TTLs too long or no expiry set",[584,1370,1371,1372,1375],{},"Review and lower TTL values; add ",[312,1373,1374],{},"EXPIRE"," if missing",[325,1377,1379],{"id":1378},"verify-connection","Verify Connection",[355,1381,1383],{"className":438,"code":1382,"language":440,"meta":360,"style":360},"redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD ping\n# Expected: PONG\n",[312,1384,1385,1409],{"__ignoreMap":360},[364,1386,1387,1389,1391,1394,1397,1400,1403,1406],{"class":366,"line":367},[364,1388,1006],{"class":453},[364,1390,1009],{"class":457},[364,1392,1393],{"class":681}," $REDIS_HOST ",[364,1395,1396],{"class":457},"-p",[364,1398,1399],{"class":681}," $REDIS_PORT ",[364,1401,1402],{"class":457},"-a",[364,1404,1405],{"class":681}," $REDIS_PASSWORD ",[364,1407,1408],{"class":457},"ping\n",[364,1410,1411],{"class":366,"line":373},[364,1412,1413],{"class":447},"# Expected: PONG\n",[1415,1416,1417],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":360,"searchDepth":367,"depth":373,"links":1419},[1420,1425,1426,1427,1428,1434],{"id":322,"depth":373,"text":323,"children":1421},[1422,1423,1424],{"id":327,"depth":379,"text":328},{"id":391,"depth":379,"text":392},{"id":434,"depth":379,"text":435},{"id":554,"depth":373,"text":555},{"id":652,"depth":373,"text":653},{"id":854,"depth":373,"text":855},{"id":973,"depth":373,"text":974,"children":1429},[1430,1431,1432,1433],{"id":1030,"depth":379,"text":1031},{"id":1104,"depth":379,"text":1105},{"id":1204,"depth":379,"text":1205},{"id":1237,"depth":379,"text":1238},{"id":1279,"depth":373,"text":1280,"children":1435},[1436],{"id":1378,"depth":379,"text":1379},"Redis setup, cache key patterns, and common CLI commands used in booki-api.","md",null,{},{"icon":48},{"title":295,"description":1437},"XnrQuGMN1Kz61citc9kHG6TxfgNBF_g9SR-njkqQYcs",[1445,1447],{"title":291,"path":292,"stem":293,"description":1446,"icon":124,"children":-1},"Understanding multi-tenant architecture, data isolation, and tenant slug resolution strategies.",{"title":299,"path":300,"stem":301,"description":1448,"icon":302,"children":-1},"Maya subscription management for organizations in booki-api — plans, payment history, webhook handling, and the checkout flow.",1777787844708]