[{"data":1,"prerenderedAt":837},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fproject\u002Fcontributing":143,"\u002Fdocs\u002Fproject\u002Fcontributing-surround":833},[4],{"title":5,"path":6,"stem":7,"children":8,"page":32},"Docs","\u002Fdocs","docs",[9,33,58,79,112,117],{"title":10,"path":11,"stem":12,"children":13,"page":32},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002Fgetting-started",[14,18,23,28],{"title":10,"path":15,"stem":16,"order":17},"\u002Fdocs\u002Fgetting-started\u002F_dir","docs\u002Fgetting-started\u002F_dir",1,{"title":19,"path":20,"stem":21,"order":22},"Configuration Reference","\u002Fdocs\u002Fgetting-started\u002Fconfiguration","docs\u002Fgetting-started\u002Fconfiguration",2,{"title":24,"path":25,"stem":26,"order":27},"Deployment Guide","\u002Fdocs\u002Fgetting-started\u002Fdeployment","docs\u002Fgetting-started\u002Fdeployment",3,{"title":29,"path":30,"stem":31,"order":17},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002Fgetting-started\u002Fquick-start",false,{"title":34,"path":35,"stem":36,"children":37,"page":32},"Guides","\u002Fdocs\u002Fguides","docs\u002Fguides",[38,41,45,49,54],{"title":34,"path":39,"stem":40,"order":22},"\u002Fdocs\u002Fguides\u002F_dir","docs\u002Fguides\u002F_dir",{"title":42,"path":43,"stem":44,"order":22},"Notifications","\u002Fdocs\u002Fguides\u002Fnotifications","docs\u002Fguides\u002Fnotifications",{"title":46,"path":47,"stem":48,"order":17},"Scoring Algorithm","\u002Fdocs\u002Fguides\u002Fscoring","docs\u002Fguides\u002Fscoring",{"title":50,"path":51,"stem":52,"order":53},"Sunset Mode","\u002Fdocs\u002Fguides\u002Fsunset-mode","docs\u002Fguides\u002Fsunset-mode",4,{"title":55,"path":56,"stem":57,"order":27},"Troubleshooting","\u002Fdocs\u002Fguides\u002Ftroubleshooting","docs\u002Fguides\u002Ftroubleshooting",{"title":59,"path":60,"stem":61,"children":62,"page":32},"Project","\u002Fdocs\u002Fproject","docs\u002Fproject",[63,67,71,75],{"title":59,"path":64,"stem":65,"order":66},"\u002Fdocs\u002Fproject\u002F_dir","docs\u002Fproject\u002F_dir",6,{"title":68,"path":69,"stem":70,"order":27},"Changelog","\u002Fdocs\u002Fproject\u002Fchangelog","docs\u002Fproject\u002Fchangelog",{"title":72,"path":73,"stem":74,"order":17},"Contributing","\u002Fdocs\u002Fproject\u002Fcontributing","docs\u002Fproject\u002Fcontributing",{"title":76,"path":77,"stem":78,"order":22},"Contributors","\u002Fdocs\u002Fproject\u002Fcontributors","docs\u002Fproject\u002Fcontributors",{"title":80,"path":81,"stem":82,"children":83,"page":32},"Reference","\u002Fdocs\u002Freference","docs\u002Freference",[84,87,108],{"title":80,"path":85,"stem":86,"order":27},"\u002Fdocs\u002Freference\u002F_dir","docs\u002Freference\u002F_dir",{"title":88,"path":89,"stem":90,"children":91,"page":32},"Api","\u002Fdocs\u002Freference\u002Fapi","docs\u002Freference\u002Fapi",[92,96,100,104],{"title":93,"path":94,"stem":95,"order":22},"API Reference","\u002Fdocs\u002Freference\u002Fapi\u002F_dir","docs\u002Freference\u002Fapi\u002F_dir",{"title":97,"path":98,"stem":99,"order":22},"API Examples","\u002Fdocs\u002Freference\u002Fapi\u002Fexamples","docs\u002Freference\u002Fapi\u002Fexamples",{"title":101,"path":102,"stem":103,"order":53},"API Versioning & Stability Guarantees","\u002Fdocs\u002Freference\u002Fapi\u002Fversioning","docs\u002Freference\u002Fapi\u002Fversioning",{"title":105,"path":106,"stem":107,"order":27},"Common Workflows","\u002Fdocs\u002Freference\u002Fapi\u002Fworkflows","docs\u002Freference\u002Fapi\u002Fworkflows",{"title":109,"path":110,"stem":111,"order":17},"Architecture","\u002Fdocs\u002Freference\u002Farchitecture","docs\u002Freference\u002Farchitecture",{"title":113,"path":114,"stem":115,"order":116},"Release Workflow","\u002Fdocs\u002Freleasing","docs\u002Freleasing",5,{"title":118,"path":119,"stem":120,"children":121,"order":17},"Security Policy","\u002Fdocs\u002Fsecurity","docs\u002Fsecurity\u002Findex",[122,123,127,131,134,137,140],{"title":118,"path":119,"stem":120,"order":17},{"title":124,"path":125,"stem":126,"order":53},"Security","\u002Fdocs\u002Fsecurity\u002F_dir","docs\u002Fsecurity\u002F_dir",{"title":128,"path":129,"stem":130,"order":22},"OWASP ZAP API Scan — Baseline Report","\u002Fdocs\u002Fsecurity\u002Fzap-baseline-20260310","docs\u002Fsecurity\u002Fzap-baseline-20260310",{"title":128,"path":132,"stem":133,"order":27},"\u002Fdocs\u002Fsecurity\u002Fzap-baseline-20260316","docs\u002Fsecurity\u002Fzap-baseline-20260316",{"title":128,"path":135,"stem":136,"order":53},"\u002Fdocs\u002Fsecurity\u002Fzap-baseline-20260323","docs\u002Fsecurity\u002Fzap-baseline-20260323",{"title":128,"path":138,"stem":139,"order":116},"\u002Fdocs\u002Fsecurity\u002Fzap-baseline-20260324","docs\u002Fsecurity\u002Fzap-baseline-20260324",{"title":128,"path":141,"stem":142},"\u002Fdocs\u002Fsecurity\u002Fzap-baseline-20260406","docs\u002Fsecurity\u002Fzap-baseline-20260406",{"id":144,"title":72,"body":145,"description":151,"extension":827,"links":828,"meta":829,"navigation":830,"path":73,"seo":831,"stem":74,"__hash__":832},"docs\u002Fdocs\u002Fproject\u002Fcontributing.md",{"type":146,"value":147,"toc":812},"minimark",[148,152,157,160,195,199,204,213,217,297,300,303,414,421,425,477,481,484,503,510,513,549,552,577,582,601,610,615,621,625,636,641,675,684,688,691,729,735,739,753,757,764,768,771,789,808],[149,150,151],"p",{},"Thank you for your interest in contributing to Capacitarr! This document outlines the process for contributing and the legal requirements.",[153,154,156],"h2",{"id":155},"contributor-license-agreement-cla","Contributor License Agreement (CLA)",[149,158,159],{},"By submitting a pull request or otherwise contributing to this project, you agree to the following terms:",[161,162,163,171,177,183],"ol",{},[164,165,166,170],"li",{},[167,168,169],"strong",{},"License Grant",": You grant Starshadow Studios a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license to use, reproduce, modify, distribute, and sublicense your contributions under any license terms, including the PolyForm Noncommercial 1.0.0 license or any successor license chosen by the project maintainers.",[164,172,173,176],{},[167,174,175],{},"Original Work",": You represent that your contribution is your original work and that you have the legal right to grant this license. If your employer has rights to intellectual property that you create, you represent that you have received permission to make contributions on behalf of that employer.",[164,178,179,182],{},[167,180,181],{},"No Warranty",": You provide your contributions on an \"as is\" basis, without warranties or conditions of any kind.",[164,184,185,188,189,194],{},[167,186,187],{},"Acknowledgment",": You acknowledge that this project is licensed under the ",[190,191,193],"a",{"href":192},"LICENSE","PolyForm Noncommercial 1.0.0"," license and that your contributions will be subject to the same license terms.",[153,196,198],{"id":197},"how-to-contribute","How to Contribute",[200,201,203],"h3",{"id":202},"reporting-issues","Reporting Issues",[205,206,207,210],"ul",{},[164,208,209],{},"Use the project's issue tracker to report bugs or request features",[164,211,212],{},"Include as much detail as possible: steps to reproduce, expected behavior, actual behavior, environment details",[200,214,216],{"id":215},"submitting-changes","Submitting Changes",[161,218,219,222,268,271,291,294],{},[164,220,221],{},"Fork the repository",[164,223,224,225,229,230],{},"Create a feature branch from ",[226,227,228],"code",{},"main"," following branch naming conventions:\n",[205,231,232,238,244,250,256,262],{},[164,233,234,237],{},[226,235,236],{},"feature\u002F"," — New features",[164,239,240,243],{},[226,241,242],{},"fix\u002F"," — Bug fixes",[164,245,246,249],{},[226,247,248],{},"refactor\u002F"," — Code refactoring",[164,251,252,255],{},[226,253,254],{},"docs\u002F"," — Documentation changes",[164,257,258,261],{},[226,259,260],{},"test\u002F"," — Test improvements",[164,263,264,267],{},[226,265,266],{},"chore\u002F"," — Maintenance tasks",[164,269,270],{},"Make your changes following the project's coding standards",[164,272,273,274,280,281],{},"Write clear, atomic commits using ",[190,275,279],{"href":276,"rel":277},"https:\u002F\u002Fwww.conventionalcommits.org\u002F",[278],"nofollow","Conventional Commits"," format:\n",[282,283,288],"pre",{"className":284,"code":286,"language":287},[285],"language-text","feat(component): add new feature\nfix(api): resolve connection timeout\ndocs: update installation guide\n","text",[226,289,286],{"__ignoreMap":290},"",[164,292,293],{},"Ensure all tests pass",[164,295,296],{},"Submit a pull request with a clear description of your changes",[200,298,109],{"id":299},"architecture",[149,301,302],{},"Capacitarr uses a layered architecture with clear separation of concerns:",[205,304,305,311,329,386,392,402,408],{},[164,306,307,310],{},[167,308,309],{},"HTTP Layer"," — Thin route handlers that parse requests, call services, and return responses",[164,312,313,316,317,320,321,324,325,328],{},[167,314,315],{},"Service Layer"," — All business logic lives in ",[226,318,319],{},"backend\u002Finternal\u002Fservices\u002F",". Each service receives a ",[226,322,323],{},"*gorm.DB"," and ",[226,326,327],{},"*events.EventBus"," via constructor injection — no global state",[164,330,331,334,335,338,339,338,342,338,345,338,348,338,351,338,354,338,357,338,360,338,363,338,366,338,369,338,372,338,375,338,378,381,382,385],{},[167,332,333],{},"Integration Layer"," — Capability-based interfaces (",[226,336,337],{},"CollectionDataProvider",", ",[226,340,341],{},"CollectionNameFetcher",[226,343,344],{},"CollectionResolver",[226,346,347],{},"Connectable",[226,349,350],{},"DiskReporter",[226,352,353],{},"LabelDataProvider",[226,355,356],{},"LabelManager",[226,358,359],{},"LabelNameFetcher",[226,361,362],{},"MediaDeleter",[226,364,365],{},"MediaSource",[226,367,368],{},"PosterManager",[226,370,371],{},"RequestProvider",[226,373,374],{},"RuleValueFetcher",[226,376,377],{},"WatchDataProvider",[226,379,380],{},"WatchlistProvider","). The ",[226,383,384],{},"IntegrationRegistry"," provides runtime capability discovery.",[164,387,388,391],{},[167,389,390],{},"Enrichment Pipeline"," — Composable enrichers auto-discovered from registry capabilities (watch data, requests, watchlists, collections, cross-references)",[164,393,394,397,398,401],{},[167,395,396],{},"Scoring Engine"," — Pluggable ",[226,399,400],{},"ScoringFactor"," interface for each scoring dimension. New factors can be added without modifying the evaluator.",[164,403,404,407],{},[167,405,406],{},"Event Bus"," — A typed pub\u002Fsub system with fan-out to three subscribers: activity persister (dashboard feed), notification dispatcher (Discord\u002FApprise), and SSE broadcaster (real-time browser updates)",[164,409,410,413],{},[167,411,412],{},"Data Layer"," — SQLite via GORM with SQL migrations",[149,415,416,417,420],{},"For the full architecture documentation with diagrams, see ",[190,418,419],{"href":110},"docs\u002Freference\u002Farchitecture.md",".",[200,422,424],{"id":423},"code-standards","Code Standards",[205,426,427,441,447,453,459,465,471],{},[164,428,429,432,433,436,437,440],{},[167,430,431],{},"Go backend",": Follow ",[226,434,435],{},"gofmt"," formatting; ",[226,438,439],{},"golangci-lint"," is run automatically via Docker",[164,442,443,446],{},[167,444,445],{},"Vue frontend",": Follow the project's ESLint and Prettier configuration; use shadcn-vue components (not raw HTML elements); use ECharts via DashboardCard for analytics",[164,448,449,452],{},[167,450,451],{},"Commits",": Use Conventional Commits format (required for changelog generation)",[164,454,455,458],{},[167,456,457],{},"Documentation",": Update relevant docs when changing user-facing behavior",[164,460,461,464],{},[167,462,463],{},"Services",": New business logic must be added to the service layer, not inline in route handlers. All DB access — both reads and writes — must go through services.",[164,466,467,470],{},[167,468,469],{},"Integrations",": New integration clients must implement capability interfaces (not a monolithic interface)",[164,472,473,476],{},[167,474,475],{},"Events",": All user-visible actions should publish typed events to the event bus",[200,478,480],{"id":479},"local-development-checks","Local Development Checks",[149,482,483],{},"Run the full CI pipeline locally before pushing:",[282,485,489],{"className":486,"code":487,"language":488,"meta":290,"style":290},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","make ci\n","bash",[226,490,491],{"__ignoreMap":290},[492,493,495,499],"span",{"class":494,"line":17},"line",[492,496,498],{"class":497},"sBMFI","make",[492,500,502],{"class":501},"sfazB"," ci\n",[149,504,505,506,509],{},"This runs lint, test, and security checks using the ",[167,507,508],{},"same Docker images"," as the GitHub Actions CI pipeline. No additional tool installation required beyond Docker and pnpm.",[149,511,512],{},"Individual stages can be run separately:",[282,514,516],{"className":486,"code":515,"language":488,"meta":290,"style":290},"make lint:ci       # golangci-lint + ESLint + Prettier format check + TypeScript typecheck\nmake test:ci       # go test + vitest\nmake security:ci   # govulncheck + pnpm audit + trivy + gitleaks + semgrep\n",[226,517,518,529,539],{"__ignoreMap":290},[492,519,520,522,525],{"class":494,"line":17},[492,521,498],{"class":497},[492,523,524],{"class":501}," lint:ci",[492,526,528],{"class":527},"sHwdD","       # golangci-lint + ESLint + Prettier format check + TypeScript typecheck\n",[492,530,531,533,536],{"class":494,"line":22},[492,532,498],{"class":497},[492,534,535],{"class":501}," test:ci",[492,537,538],{"class":527},"       # go test + vitest\n",[492,540,541,543,546],{"class":494,"line":27},[492,542,498],{"class":497},[492,544,545],{"class":501}," security:ci",[492,547,548],{"class":527},"   # govulncheck + pnpm audit + trivy + gitleaks + semgrep\n",[149,550,551],{},"For auto-fixing lint and formatting issues during development:",[282,553,555],{"className":486,"code":554,"language":488,"meta":290,"style":290},"make lint          # ESLint --fix + golangci-lint (via Docker)\nmake format        # Prettier --write + gofmt\n",[226,556,557,567],{"__ignoreMap":290},[492,558,559,561,564],{"class":494,"line":17},[492,560,498],{"class":497},[492,562,563],{"class":501}," lint",[492,565,566],{"class":527},"          # ESLint --fix + golangci-lint (via Docker)\n",[492,568,569,571,574],{"class":494,"line":22},[492,570,498],{"class":497},[492,572,573],{"class":501}," format",[492,575,576],{"class":527},"        # Prettier --write + gofmt\n",[149,578,579],{},[167,580,581],{},"Full build verification via Docker:",[282,583,585],{"className":486,"code":584,"language":488,"meta":290,"style":290},"docker compose up --build\n",[226,586,587],{"__ignoreMap":290},[492,588,589,592,595,598],{"class":494,"line":17},[492,590,591],{"class":497},"docker",[492,593,594],{"class":501}," compose",[492,596,597],{"class":501}," up",[492,599,600],{"class":501}," --build\n",[602,603,604],"blockquote",{},[149,605,606,609],{},[167,607,608],{},"Note:"," Do not run the backend or frontend directly for testing. Use Docker Compose to ensure the build matches the production environment.",[149,611,612],{},[167,613,614],{},"Recommended workflow:",[282,616,619],{"className":617,"code":618,"language":287},[285],"make lint format → make ci → commit → push\n     (fix)         (verify)\n",[226,620,618],{"__ignoreMap":290},[200,622,624],{"id":623},"docker-image-pinning","Docker Image Pinning",[149,626,627,628,631,632,635],{},"All Docker images in the ",[226,629,630],{},"Makefile"," and CI workflows are pinned to specific version tags (no ",[226,633,634],{},":latest","). This protects against supply chain attacks where a compromised upstream image could silently enter our pipeline.",[149,637,638],{},[167,639,640],{},"When updating pinned versions:",[161,642,643,646,653,663,669],{},[164,644,645],{},"Pull the new image version locally",[164,647,648,649,652],{},"Run ",[226,650,651],{},"make ci"," to verify compatibility",[164,654,655,656,659,660,662],{},"Update the version tag in ",[167,657,658],{},"both"," ",[226,661,630],{}," and CI workflows — they must always match",[164,664,665,666],{},"Update the pinned versions table in ",[226,667,668],{},"SECURITY.md",[164,670,671,672],{},"Commit with ",[226,673,674],{},"chore(deps): bump \u003Ctool> to v\u003Cversion>",[149,676,677,683],{},[167,678,679,680,682],{},"Never re-introduce ",[226,681,634],{}," tags"," or curl-pipe-to-shell install patterns in CI jobs.",[200,685,687],{"id":686},"cicd-pipeline","CI\u002FCD Pipeline",[149,689,690],{},"Every push and pull request triggers a GitHub Actions CI pipeline with these stages:",[161,692,693,702,711,717],{},[164,694,695,698,699,701],{},[167,696,697],{},"Lint"," — ",[226,700,439],{}," (Go), ESLint + Prettier format check + TypeScript typecheck (frontend)",[164,703,704,698,707,710],{},[167,705,706],{},"Test",[226,708,709],{},"go test"," and Vitest for the frontend",[164,712,713,716],{},[167,714,715],{},"Build"," — Docker image build verification",[164,718,719,698,721,724,725,728],{},[167,720,124],{},[226,722,723],{},"govulncheck"," (Go), ",[226,726,727],{},"pnpm audit"," (frontend), Trivy (filesystem vulnerability scan), Gitleaks (secret scanning), Semgrep (SAST)",[149,730,731,732,734],{},"The ",[226,733,651],{}," command runs the same checks using the same Docker images, so if it passes locally it will pass in CI. Ensure all CI checks pass before requesting review.",[200,736,738],{"id":737},"pull-request-guidelines","Pull Request Guidelines",[205,740,741,744,747,750],{},[164,742,743],{},"Keep PRs focused — one logical change per PR",[164,745,746],{},"Include tests for new functionality where possible",[164,748,749],{},"Update documentation if your change affects user-facing behavior",[164,751,752],{},"Respond to review feedback promptly",[153,754,756],{"id":755},"questions","Questions?",[149,758,759,760,763],{},"If you have questions about contributing, open an issue with the ",[226,761,762],{},"question"," label.",[153,765,767],{"id":766},"support","Support",[149,769,770],{},"Capacitarr is free and always will be. If it's useful to you, I'd love for you to donate to one of these animal rescue organizations:",[205,772,773,781],{},[164,774,775,780],{},[190,776,779],{"href":777,"rel":778},"https:\u002F\u002Fuanimals.org\u002Fen\u002F",[278],"UAnimals"," — Rescuing and protecting animals in Ukraine",[164,782,783,788],{},[190,784,787],{"href":785,"rel":786},"https:\u002F\u002Fwww.aspca.org\u002Fways-to-help",[278],"ASPCA"," — Preventing cruelty to animals in the US",[149,790,791,792,338,797,802,803,420],{},"You can also support the developer directly via ",[190,793,796],{"href":794,"rel":795},"https:\u002F\u002Fgithub.com\u002Fsponsors\u002Fghent",[278],"GitHub Sponsors",[190,798,801],{"href":799,"rel":800},"https:\u002F\u002Fko-fi.com\u002Fghent",[278],"Ko-fi",", or ",[190,804,807],{"href":805,"rel":806},"https:\u002F\u002Fbuymeacoffee.com\u002Fghentgames",[278],"Buy Me a Coffee",[809,810,811],"style",{},"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 .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}",{"title":290,"searchDepth":17,"depth":22,"links":813},[814,815,825,826],{"id":155,"depth":22,"text":156},{"id":197,"depth":22,"text":198,"children":816},[817,818,819,820,821,822,823,824],{"id":202,"depth":27,"text":203},{"id":215,"depth":27,"text":216},{"id":299,"depth":27,"text":109},{"id":423,"depth":27,"text":424},{"id":479,"depth":27,"text":480},{"id":623,"depth":27,"text":624},{"id":686,"depth":27,"text":687},{"id":737,"depth":27,"text":738},{"id":755,"depth":22,"text":756},{"id":766,"depth":22,"text":767},"md",null,{},{"order":17},{"title":72,"description":151},"PJYIj0kVcyLPsaJDJdjAnrrY4ZiiAxlYSdGc2m4vX00",[834,835],{"title":68,"path":69,"stem":70,"description":290,"order":27,"children":-1},{"title":76,"path":77,"stem":78,"description":836,"order":22,"children":-1},"Thank you to everyone who has contributed to Capacitarr!",1776649613243]