mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 07:27:15 +08:00
refactor: strengthen architecture CI gates and runtime contracts
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"application": {
|
||||
"covered_lines": 0,
|
||||
"percent": 0.0,
|
||||
"statements": 0
|
||||
},
|
||||
"domain": {
|
||||
"covered_lines": 0,
|
||||
"percent": 0.0,
|
||||
"statements": 0
|
||||
}
|
||||
}
|
||||
+57
-32
@@ -13,8 +13,8 @@
|
||||
"runtime_to_db": [],
|
||||
"workflow_to_db": []
|
||||
},
|
||||
"edge_count": 6644,
|
||||
"edge_sha256": "6d011ba65df8afe21dec208fd09a3a2a314743ae282db5ce411307b9d967fd00",
|
||||
"edge_count": 6661,
|
||||
"edge_sha256": "e276e75348004a89b7f10f3520ce5eb935130cf11a8b45dc371e79937f5d67e3",
|
||||
"edges": [
|
||||
"app -> app.runtime",
|
||||
"app -> app.runtime.compat",
|
||||
@@ -1661,7 +1661,7 @@
|
||||
"app.api.dependencies.workflow -> app.application.scheduling",
|
||||
"app.api.dependencies.workflow -> app.application.workflow",
|
||||
"app.api.dependencies.workflow -> app.runtime",
|
||||
"app.api.dependencies.workflow -> app.runtime.config",
|
||||
"app.api.dependencies.workflow -> app.runtime.stop",
|
||||
"app.api.dependencies.workflow -> app.startup",
|
||||
"app.api.dependencies.workflow -> app.startup.composition",
|
||||
"app.api.dependencies.workflow -> app.startup.composition.context",
|
||||
@@ -1700,10 +1700,10 @@
|
||||
"app.api.endpoints.agent -> app.chain",
|
||||
"app.api.endpoints.agent -> app.chain.message",
|
||||
"app.api.endpoints.agent -> app.runtime",
|
||||
"app.api.endpoints.agent -> app.runtime.config",
|
||||
"app.api.endpoints.agent -> app.runtime.execution",
|
||||
"app.api.endpoints.agent -> app.runtime.localization",
|
||||
"app.api.endpoints.agent -> app.runtime.log",
|
||||
"app.api.endpoints.agent -> app.runtime.stop",
|
||||
"app.api.endpoints.agent -> app.schemas",
|
||||
"app.api.endpoints.agent -> app.schemas.agent",
|
||||
"app.api.endpoints.agent -> app.schemas.message",
|
||||
@@ -2316,7 +2316,6 @@
|
||||
"app.api.endpoints.system -> app.chain.media",
|
||||
"app.api.endpoints.system -> app.chain.mediaserver",
|
||||
"app.api.endpoints.system -> app.chain.search",
|
||||
"app.api.endpoints.system -> app.chain.system",
|
||||
"app.api.endpoints.system -> app.domain",
|
||||
"app.api.endpoints.system -> app.domain.metainfo",
|
||||
"app.api.endpoints.system -> app.foundation",
|
||||
@@ -2332,6 +2331,7 @@
|
||||
"app.api.endpoints.system -> app.runtime.progress",
|
||||
"app.api.endpoints.system -> app.runtime.scheduling",
|
||||
"app.api.endpoints.system -> app.runtime.state",
|
||||
"app.api.endpoints.system -> app.runtime.stop",
|
||||
"app.api.endpoints.system -> app.runtime.version",
|
||||
"app.api.endpoints.system -> app.schemas",
|
||||
"app.api.endpoints.system -> app.schemas.common",
|
||||
@@ -2394,8 +2394,8 @@
|
||||
"app.api.endpoints.transfer -> app.chain.media",
|
||||
"app.api.endpoints.transfer -> app.chain.transfer",
|
||||
"app.api.endpoints.transfer -> app.runtime",
|
||||
"app.api.endpoints.transfer -> app.runtime.config",
|
||||
"app.api.endpoints.transfer -> app.runtime.log",
|
||||
"app.api.endpoints.transfer -> app.runtime.stop",
|
||||
"app.api.endpoints.transfer -> app.schemas",
|
||||
"app.api.endpoints.transfer -> app.schemas.common",
|
||||
"app.api.endpoints.transfer -> app.schemas.response",
|
||||
@@ -2544,6 +2544,8 @@
|
||||
"app.application.chain.context -> app.application.chain.data",
|
||||
"app.application.chain.context -> app.application.chain.durable_events",
|
||||
"app.application.chain.context -> app.application.configuration",
|
||||
"app.application.chain.context -> app.runtime",
|
||||
"app.application.chain.context -> app.runtime.stop",
|
||||
"app.application.chain.durable_events -> app.application",
|
||||
"app.application.chain.durable_events -> app.application.history",
|
||||
"app.application.chain.durable_events -> app.domain",
|
||||
@@ -2689,8 +2691,8 @@
|
||||
"app.application.messaging.message -> app.foundation.size",
|
||||
"app.application.messaging.message -> app.runtime",
|
||||
"app.application.messaging.message -> app.runtime.cache",
|
||||
"app.application.messaging.message -> app.runtime.config",
|
||||
"app.application.messaging.message -> app.runtime.log",
|
||||
"app.application.messaging.message -> app.runtime.stop",
|
||||
"app.application.messaging.message -> app.schemas",
|
||||
"app.application.messaging.message -> app.schemas.message",
|
||||
"app.application.messaging.message -> app.schemas.tmdb",
|
||||
@@ -2993,6 +2995,8 @@
|
||||
"app.chain -> app.schemas.transfer",
|
||||
"app.chain -> app.schemas.types",
|
||||
"app.chain -> app.schemas.workflow",
|
||||
"app.chain._interaction -> app.chain",
|
||||
"app.chain._interaction -> app.chain._contracts",
|
||||
"app.chain._interaction -> app.schemas",
|
||||
"app.chain._interaction -> app.schemas.types",
|
||||
"app.chain._messaging -> app.application",
|
||||
@@ -3002,6 +3006,8 @@
|
||||
"app.chain._messaging -> app.application.messaging.agent",
|
||||
"app.chain._messaging -> app.application.messaging.message",
|
||||
"app.chain._messaging -> app.application.notification",
|
||||
"app.chain._messaging -> app.chain",
|
||||
"app.chain._messaging -> app.chain._contracts",
|
||||
"app.chain._messaging -> app.domain",
|
||||
"app.chain._messaging -> app.domain.context",
|
||||
"app.chain._messaging -> app.domain.meta",
|
||||
@@ -3023,6 +3029,7 @@
|
||||
"app.chain._music -> app.application.subscription.contract",
|
||||
"app.chain._music -> app.application.torrent",
|
||||
"app.chain._music -> app.chain",
|
||||
"app.chain._music -> app.chain._contracts",
|
||||
"app.chain._music -> app.chain.download",
|
||||
"app.chain._music -> app.chain.media",
|
||||
"app.chain._music -> app.chain.search",
|
||||
@@ -3040,6 +3047,8 @@
|
||||
"app.chain._recognition -> app.adapters.external.server",
|
||||
"app.chain._recognition -> app.application",
|
||||
"app.chain._recognition -> app.application.configuration",
|
||||
"app.chain._recognition -> app.chain",
|
||||
"app.chain._recognition -> app.chain._contracts",
|
||||
"app.chain._recognition -> app.domain",
|
||||
"app.chain._recognition -> app.domain.context",
|
||||
"app.chain._recognition -> app.domain.meta",
|
||||
@@ -3065,6 +3074,7 @@
|
||||
"app.chain._transfer -> app.application.history",
|
||||
"app.chain._transfer -> app.application.transfer",
|
||||
"app.chain._transfer -> app.chain",
|
||||
"app.chain._transfer -> app.chain._contracts",
|
||||
"app.chain._transfer -> app.chain.media",
|
||||
"app.chain._transfer -> app.chain.storage",
|
||||
"app.chain._transfer -> app.chain.subscribe",
|
||||
@@ -3139,9 +3149,9 @@
|
||||
"app.chain.download -> app.foundation.text",
|
||||
"app.chain.download -> app.runtime",
|
||||
"app.chain.download -> app.runtime.cache",
|
||||
"app.chain.download -> app.runtime.config",
|
||||
"app.chain.download -> app.runtime.events",
|
||||
"app.chain.download -> app.runtime.log",
|
||||
"app.chain.download -> app.runtime.stop",
|
||||
"app.chain.download -> app.runtime.thread",
|
||||
"app.chain.download -> app.schemas",
|
||||
"app.chain.download -> app.schemas.event",
|
||||
@@ -3232,8 +3242,8 @@
|
||||
"app.chain.mediaserver -> app.application.security.url",
|
||||
"app.chain.mediaserver -> app.chain",
|
||||
"app.chain.mediaserver -> app.runtime",
|
||||
"app.chain.mediaserver -> app.runtime.config",
|
||||
"app.chain.mediaserver -> app.runtime.log",
|
||||
"app.chain.mediaserver -> app.runtime.stop",
|
||||
"app.chain.mediaserver -> app.schemas",
|
||||
"app.chain.mediaserver -> app.schemas.mediaserver",
|
||||
"app.chain.mediaserver -> app.schemas.types",
|
||||
@@ -3286,9 +3296,9 @@
|
||||
"app.chain.recommend -> app.foundation.singleton",
|
||||
"app.chain.recommend -> app.runtime",
|
||||
"app.chain.recommend -> app.runtime.cache",
|
||||
"app.chain.recommend -> app.runtime.config",
|
||||
"app.chain.recommend -> app.runtime.execution",
|
||||
"app.chain.recommend -> app.runtime.log",
|
||||
"app.chain.recommend -> app.runtime.stop",
|
||||
"app.chain.recommend -> app.schemas",
|
||||
"app.chain.recommend -> app.schemas.media",
|
||||
"app.chain.recommend -> app.schemas.types",
|
||||
@@ -3337,11 +3347,11 @@
|
||||
"app.chain.search -> app.foundation.size",
|
||||
"app.chain.search -> app.foundation.text",
|
||||
"app.chain.search -> app.runtime",
|
||||
"app.chain.search -> app.runtime.config",
|
||||
"app.chain.search -> app.runtime.events",
|
||||
"app.chain.search -> app.runtime.execution",
|
||||
"app.chain.search -> app.runtime.log",
|
||||
"app.chain.search -> app.runtime.progress",
|
||||
"app.chain.search -> app.runtime.stop",
|
||||
"app.chain.search -> app.runtime.tasks",
|
||||
"app.chain.search -> app.schemas",
|
||||
"app.chain.search -> app.schemas.media",
|
||||
@@ -3373,9 +3383,9 @@
|
||||
"app.chain.site -> app.foundation.size",
|
||||
"app.chain.site -> app.foundation.url",
|
||||
"app.chain.site -> app.runtime",
|
||||
"app.chain.site -> app.runtime.config",
|
||||
"app.chain.site -> app.runtime.events",
|
||||
"app.chain.site -> app.runtime.log",
|
||||
"app.chain.site -> app.runtime.stop",
|
||||
"app.chain.site -> app.schemas",
|
||||
"app.chain.site -> app.schemas.message",
|
||||
"app.chain.site -> app.schemas.notification",
|
||||
@@ -3424,9 +3434,9 @@
|
||||
"app.chain.subscribe -> app.domain.meta.words",
|
||||
"app.chain.subscribe -> app.domain.metainfo",
|
||||
"app.chain.subscribe -> app.runtime",
|
||||
"app.chain.subscribe -> app.runtime.config",
|
||||
"app.chain.subscribe -> app.runtime.events",
|
||||
"app.chain.subscribe -> app.runtime.log",
|
||||
"app.chain.subscribe -> app.runtime.stop",
|
||||
"app.chain.subscribe -> app.schemas",
|
||||
"app.chain.subscribe -> app.schemas.event",
|
||||
"app.chain.subscribe -> app.schemas.media",
|
||||
@@ -3479,8 +3489,8 @@
|
||||
"app.chain.torrents -> app.foundation",
|
||||
"app.chain.torrents -> app.foundation.text",
|
||||
"app.chain.torrents -> app.runtime",
|
||||
"app.chain.torrents -> app.runtime.config",
|
||||
"app.chain.torrents -> app.runtime.log",
|
||||
"app.chain.torrents -> app.runtime.stop",
|
||||
"app.chain.torrents -> app.schemas",
|
||||
"app.chain.torrents -> app.schemas.media",
|
||||
"app.chain.torrents -> app.schemas.message",
|
||||
@@ -3498,6 +3508,7 @@
|
||||
"app.chain.transfer -> app.chain._transfer",
|
||||
"app.chain.transfer -> app.chain.media",
|
||||
"app.chain.transfer -> app.chain.storage",
|
||||
"app.chain.transfer -> app.chain.subscribe",
|
||||
"app.chain.transfer -> app.chain.tmdb",
|
||||
"app.chain.transfer -> app.domain",
|
||||
"app.chain.transfer -> app.domain.context",
|
||||
@@ -3513,6 +3524,7 @@
|
||||
"app.chain.transfer -> app.runtime.log",
|
||||
"app.chain.transfer -> app.runtime.progress",
|
||||
"app.chain.transfer -> app.runtime.reload",
|
||||
"app.chain.transfer -> app.runtime.stop",
|
||||
"app.chain.transfer -> app.schemas",
|
||||
"app.chain.transfer -> app.schemas.event",
|
||||
"app.chain.transfer -> app.schemas.exception",
|
||||
@@ -3545,10 +3557,10 @@
|
||||
"app.chain.workflow -> app.application.workflow",
|
||||
"app.chain.workflow -> app.chain",
|
||||
"app.chain.workflow -> app.runtime",
|
||||
"app.chain.workflow -> app.runtime.config",
|
||||
"app.chain.workflow -> app.runtime.events",
|
||||
"app.chain.workflow -> app.runtime.execution",
|
||||
"app.chain.workflow -> app.runtime.log",
|
||||
"app.chain.workflow -> app.runtime.stop",
|
||||
"app.chain.workflow -> app.schemas",
|
||||
"app.chain.workflow -> app.schemas.types",
|
||||
"app.chain.workflow -> app.schemas.workflow",
|
||||
@@ -3995,6 +4007,7 @@
|
||||
"app.main -> app.runtime",
|
||||
"app.main -> app.runtime.config",
|
||||
"app.main -> app.runtime.settings",
|
||||
"app.main -> app.runtime.stop",
|
||||
"app.main -> app.runtime.topology",
|
||||
"app.modules -> app.runtime",
|
||||
"app.modules -> app.runtime.extensions",
|
||||
@@ -4299,9 +4312,9 @@
|
||||
"app.modules.filemanager.storages.alipan -> app.modules.filemanager",
|
||||
"app.modules.filemanager.storages.alipan -> app.modules.filemanager.storages",
|
||||
"app.modules.filemanager.storages.alipan -> app.runtime",
|
||||
"app.modules.filemanager.storages.alipan -> app.runtime.config",
|
||||
"app.modules.filemanager.storages.alipan -> app.runtime.log",
|
||||
"app.modules.filemanager.storages.alipan -> app.runtime.settings",
|
||||
"app.modules.filemanager.storages.alipan -> app.runtime.stop",
|
||||
"app.modules.filemanager.storages.alipan -> app.schemas",
|
||||
"app.modules.filemanager.storages.alipan -> app.schemas.exception",
|
||||
"app.modules.filemanager.storages.alipan -> app.schemas.file",
|
||||
@@ -4318,9 +4331,9 @@
|
||||
"app.modules.filemanager.storages.alist -> app.modules.filemanager.storages",
|
||||
"app.modules.filemanager.storages.alist -> app.runtime",
|
||||
"app.modules.filemanager.storages.alist -> app.runtime.cache",
|
||||
"app.modules.filemanager.storages.alist -> app.runtime.config",
|
||||
"app.modules.filemanager.storages.alist -> app.runtime.log",
|
||||
"app.modules.filemanager.storages.alist -> app.runtime.settings",
|
||||
"app.modules.filemanager.storages.alist -> app.runtime.stop",
|
||||
"app.modules.filemanager.storages.alist -> app.schemas",
|
||||
"app.modules.filemanager.storages.alist -> app.schemas.exception",
|
||||
"app.modules.filemanager.storages.alist -> app.schemas.file",
|
||||
@@ -4342,9 +4355,9 @@
|
||||
"app.modules.filemanager.storages.local -> app.modules.filemanager",
|
||||
"app.modules.filemanager.storages.local -> app.modules.filemanager.storages",
|
||||
"app.modules.filemanager.storages.local -> app.runtime",
|
||||
"app.modules.filemanager.storages.local -> app.runtime.config",
|
||||
"app.modules.filemanager.storages.local -> app.runtime.log",
|
||||
"app.modules.filemanager.storages.local -> app.runtime.settings",
|
||||
"app.modules.filemanager.storages.local -> app.runtime.stop",
|
||||
"app.modules.filemanager.storages.local -> app.schemas",
|
||||
"app.modules.filemanager.storages.local -> app.schemas.exception",
|
||||
"app.modules.filemanager.storages.local -> app.schemas.file",
|
||||
@@ -4372,9 +4385,9 @@
|
||||
"app.modules.filemanager.storages.smb -> app.modules.filemanager",
|
||||
"app.modules.filemanager.storages.smb -> app.modules.filemanager.storages",
|
||||
"app.modules.filemanager.storages.smb -> app.runtime",
|
||||
"app.modules.filemanager.storages.smb -> app.runtime.config",
|
||||
"app.modules.filemanager.storages.smb -> app.runtime.log",
|
||||
"app.modules.filemanager.storages.smb -> app.runtime.settings",
|
||||
"app.modules.filemanager.storages.smb -> app.runtime.stop",
|
||||
"app.modules.filemanager.storages.smb -> app.schemas",
|
||||
"app.modules.filemanager.storages.smb -> app.schemas.exception",
|
||||
"app.modules.filemanager.storages.smb -> app.schemas.file",
|
||||
@@ -4387,10 +4400,10 @@
|
||||
"app.modules.filemanager.storages.u115 -> app.modules.filemanager",
|
||||
"app.modules.filemanager.storages.u115 -> app.modules.filemanager.storages",
|
||||
"app.modules.filemanager.storages.u115 -> app.runtime",
|
||||
"app.modules.filemanager.storages.u115 -> app.runtime.config",
|
||||
"app.modules.filemanager.storages.u115 -> app.runtime.log",
|
||||
"app.modules.filemanager.storages.u115 -> app.runtime.rate",
|
||||
"app.modules.filemanager.storages.u115 -> app.runtime.settings",
|
||||
"app.modules.filemanager.storages.u115 -> app.runtime.stop",
|
||||
"app.modules.filemanager.storages.u115 -> app.schemas",
|
||||
"app.modules.filemanager.storages.u115 -> app.schemas.exception",
|
||||
"app.modules.filemanager.storages.u115 -> app.schemas.file",
|
||||
@@ -5653,6 +5666,7 @@
|
||||
"app.runtime.config -> app.foundation.url",
|
||||
"app.runtime.config -> app.runtime",
|
||||
"app.runtime.config -> app.runtime.log",
|
||||
"app.runtime.config -> app.runtime.stop",
|
||||
"app.runtime.config -> app.runtime.version",
|
||||
"app.runtime.config -> app.schemas",
|
||||
"app.runtime.config -> app.schemas.types",
|
||||
@@ -5922,6 +5936,7 @@
|
||||
"app.scheduler -> app.runtime.progress",
|
||||
"app.scheduler -> app.runtime.reload",
|
||||
"app.scheduler -> app.runtime.scheduling",
|
||||
"app.scheduler -> app.runtime.stop",
|
||||
"app.scheduler -> app.schemas",
|
||||
"app.scheduler -> app.schemas.dashboard",
|
||||
"app.scheduler -> app.schemas.message",
|
||||
@@ -6354,6 +6369,7 @@
|
||||
"app.startup.initializers.modules -> app.runtime.observability",
|
||||
"app.startup.initializers.modules -> app.runtime.settings",
|
||||
"app.startup.initializers.modules -> app.runtime.state",
|
||||
"app.startup.initializers.modules -> app.runtime.stop",
|
||||
"app.startup.initializers.modules -> app.runtime.tasks",
|
||||
"app.startup.initializers.modules -> app.runtime.thread",
|
||||
"app.startup.initializers.modules -> app.scheduler",
|
||||
@@ -6451,6 +6467,7 @@
|
||||
"app.startup.lifecycle -> app.runtime.log",
|
||||
"app.startup.lifecycle -> app.runtime.settings",
|
||||
"app.startup.lifecycle -> app.runtime.state",
|
||||
"app.startup.lifecycle -> app.runtime.stop",
|
||||
"app.startup.lifecycle -> app.runtime.tasks",
|
||||
"app.startup.lifecycle -> app.runtime.topology",
|
||||
"app.startup.lifecycle -> app.startup",
|
||||
@@ -6495,6 +6512,7 @@
|
||||
"app.workflow -> app.runtime.config",
|
||||
"app.workflow -> app.runtime.events",
|
||||
"app.workflow -> app.runtime.log",
|
||||
"app.workflow -> app.runtime.stop",
|
||||
"app.workflow -> app.schemas",
|
||||
"app.workflow -> app.schemas.types",
|
||||
"app.workflow -> app.schemas.workflow",
|
||||
@@ -6509,8 +6527,8 @@
|
||||
"app.workflow.actions.add_download -> app.domain",
|
||||
"app.workflow.actions.add_download -> app.domain.metainfo",
|
||||
"app.workflow.actions.add_download -> app.runtime",
|
||||
"app.workflow.actions.add_download -> app.runtime.config",
|
||||
"app.workflow.actions.add_download -> app.runtime.log",
|
||||
"app.workflow.actions.add_download -> app.runtime.stop",
|
||||
"app.workflow.actions.add_download -> app.schemas",
|
||||
"app.workflow.actions.add_download -> app.schemas.types",
|
||||
"app.workflow.actions.add_download -> app.schemas.workflow",
|
||||
@@ -6525,15 +6543,15 @@
|
||||
"app.workflow.actions.add_subscribe -> app.domain",
|
||||
"app.workflow.actions.add_subscribe -> app.domain.context",
|
||||
"app.workflow.actions.add_subscribe -> app.runtime",
|
||||
"app.workflow.actions.add_subscribe -> app.runtime.config",
|
||||
"app.workflow.actions.add_subscribe -> app.runtime.log",
|
||||
"app.workflow.actions.add_subscribe -> app.runtime.stop",
|
||||
"app.workflow.actions.add_subscribe -> app.schemas",
|
||||
"app.workflow.actions.add_subscribe -> app.schemas.workflow",
|
||||
"app.workflow.actions.add_subscribe -> app.workflow",
|
||||
"app.workflow.actions.add_subscribe -> app.workflow.actions",
|
||||
"app.workflow.actions.fetch_downloads -> app.runtime",
|
||||
"app.workflow.actions.fetch_downloads -> app.runtime.config",
|
||||
"app.workflow.actions.fetch_downloads -> app.runtime.log",
|
||||
"app.workflow.actions.fetch_downloads -> app.runtime.stop",
|
||||
"app.workflow.actions.fetch_downloads -> app.schemas",
|
||||
"app.workflow.actions.fetch_downloads -> app.schemas.workflow",
|
||||
"app.workflow.actions.fetch_downloads -> app.workflow",
|
||||
@@ -6546,9 +6564,9 @@
|
||||
"app.workflow.actions.fetch_medias -> app.chain",
|
||||
"app.workflow.actions.fetch_medias -> app.chain.recommend",
|
||||
"app.workflow.actions.fetch_medias -> app.runtime",
|
||||
"app.workflow.actions.fetch_medias -> app.runtime.config",
|
||||
"app.workflow.actions.fetch_medias -> app.runtime.events",
|
||||
"app.workflow.actions.fetch_medias -> app.runtime.log",
|
||||
"app.workflow.actions.fetch_medias -> app.runtime.stop",
|
||||
"app.workflow.actions.fetch_medias -> app.schemas",
|
||||
"app.workflow.actions.fetch_medias -> app.schemas.event",
|
||||
"app.workflow.actions.fetch_medias -> app.schemas.types",
|
||||
@@ -6564,8 +6582,8 @@
|
||||
"app.workflow.actions.fetch_rss -> app.domain.context",
|
||||
"app.workflow.actions.fetch_rss -> app.domain.metainfo",
|
||||
"app.workflow.actions.fetch_rss -> app.runtime",
|
||||
"app.workflow.actions.fetch_rss -> app.runtime.config",
|
||||
"app.workflow.actions.fetch_rss -> app.runtime.log",
|
||||
"app.workflow.actions.fetch_rss -> app.runtime.stop",
|
||||
"app.workflow.actions.fetch_rss -> app.schemas",
|
||||
"app.workflow.actions.fetch_rss -> app.schemas.workflow",
|
||||
"app.workflow.actions.fetch_rss -> app.workflow",
|
||||
@@ -6574,16 +6592,16 @@
|
||||
"app.workflow.actions.fetch_torrents -> app.chain.media",
|
||||
"app.workflow.actions.fetch_torrents -> app.chain.search",
|
||||
"app.workflow.actions.fetch_torrents -> app.runtime",
|
||||
"app.workflow.actions.fetch_torrents -> app.runtime.config",
|
||||
"app.workflow.actions.fetch_torrents -> app.runtime.log",
|
||||
"app.workflow.actions.fetch_torrents -> app.runtime.stop",
|
||||
"app.workflow.actions.fetch_torrents -> app.schemas",
|
||||
"app.workflow.actions.fetch_torrents -> app.schemas.types",
|
||||
"app.workflow.actions.fetch_torrents -> app.schemas.workflow",
|
||||
"app.workflow.actions.fetch_torrents -> app.workflow",
|
||||
"app.workflow.actions.fetch_torrents -> app.workflow.actions",
|
||||
"app.workflow.actions.filter_medias -> app.runtime",
|
||||
"app.workflow.actions.filter_medias -> app.runtime.config",
|
||||
"app.workflow.actions.filter_medias -> app.runtime.log",
|
||||
"app.workflow.actions.filter_medias -> app.runtime.stop",
|
||||
"app.workflow.actions.filter_medias -> app.schemas",
|
||||
"app.workflow.actions.filter_medias -> app.schemas.workflow",
|
||||
"app.workflow.actions.filter_medias -> app.workflow",
|
||||
@@ -6591,8 +6609,8 @@
|
||||
"app.workflow.actions.filter_torrents -> app.application",
|
||||
"app.workflow.actions.filter_torrents -> app.application.torrent",
|
||||
"app.workflow.actions.filter_torrents -> app.runtime",
|
||||
"app.workflow.actions.filter_torrents -> app.runtime.config",
|
||||
"app.workflow.actions.filter_torrents -> app.runtime.log",
|
||||
"app.workflow.actions.filter_torrents -> app.runtime.stop",
|
||||
"app.workflow.actions.filter_torrents -> app.schemas",
|
||||
"app.workflow.actions.filter_torrents -> app.schemas.workflow",
|
||||
"app.workflow.actions.filter_torrents -> app.workflow",
|
||||
@@ -6615,8 +6633,8 @@
|
||||
"app.workflow.actions.scan_file -> app.chain",
|
||||
"app.workflow.actions.scan_file -> app.chain.storage",
|
||||
"app.workflow.actions.scan_file -> app.runtime",
|
||||
"app.workflow.actions.scan_file -> app.runtime.config",
|
||||
"app.workflow.actions.scan_file -> app.runtime.log",
|
||||
"app.workflow.actions.scan_file -> app.runtime.stop",
|
||||
"app.workflow.actions.scan_file -> app.schemas",
|
||||
"app.workflow.actions.scan_file -> app.schemas.workflow",
|
||||
"app.workflow.actions.scan_file -> app.workflow",
|
||||
@@ -6626,8 +6644,8 @@
|
||||
"app.workflow.actions.scrape_file -> app.chain.scraping",
|
||||
"app.workflow.actions.scrape_file -> app.chain.storage",
|
||||
"app.workflow.actions.scrape_file -> app.runtime",
|
||||
"app.workflow.actions.scrape_file -> app.runtime.config",
|
||||
"app.workflow.actions.scrape_file -> app.runtime.log",
|
||||
"app.workflow.actions.scrape_file -> app.runtime.stop",
|
||||
"app.workflow.actions.scrape_file -> app.schemas",
|
||||
"app.workflow.actions.scrape_file -> app.schemas.workflow",
|
||||
"app.workflow.actions.scrape_file -> app.workflow",
|
||||
@@ -6653,14 +6671,14 @@
|
||||
"app.workflow.actions.transfer_file -> app.chain.storage",
|
||||
"app.workflow.actions.transfer_file -> app.chain.transfer",
|
||||
"app.workflow.actions.transfer_file -> app.runtime",
|
||||
"app.workflow.actions.transfer_file -> app.runtime.config",
|
||||
"app.workflow.actions.transfer_file -> app.runtime.log",
|
||||
"app.workflow.actions.transfer_file -> app.runtime.stop",
|
||||
"app.workflow.actions.transfer_file -> app.schemas",
|
||||
"app.workflow.actions.transfer_file -> app.schemas.workflow",
|
||||
"app.workflow.actions.transfer_file -> app.workflow",
|
||||
"app.workflow.actions.transfer_file -> app.workflow.actions"
|
||||
],
|
||||
"module_count": 816,
|
||||
"module_count": 818,
|
||||
"modules": [
|
||||
"app",
|
||||
"app.adapters",
|
||||
@@ -7001,6 +7019,7 @@
|
||||
"app.application.transfer",
|
||||
"app.application.workflow",
|
||||
"app.chain",
|
||||
"app.chain._contracts",
|
||||
"app.chain._interaction",
|
||||
"app.chain._messaging",
|
||||
"app.chain._music",
|
||||
@@ -7372,6 +7391,7 @@
|
||||
"app.runtime.scheduling",
|
||||
"app.runtime.settings",
|
||||
"app.runtime.state",
|
||||
"app.runtime.stop",
|
||||
"app.runtime.tasks",
|
||||
"app.runtime.thread",
|
||||
"app.runtime.topology",
|
||||
@@ -7482,6 +7502,11 @@
|
||||
"schema_version": 1,
|
||||
"scope": "MoviePilot host app excluding app/plugins",
|
||||
"strongly_connected_components": [
|
||||
[
|
||||
"app.chain",
|
||||
"app.chain._messaging",
|
||||
"app.chain._recognition"
|
||||
],
|
||||
[
|
||||
"app.modules.themoviedb",
|
||||
"app.modules.themoviedb.scraper",
|
||||
|
||||
+2155
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
"""Chain mixin Host Protocol 与依赖方向门禁。"""
|
||||
|
||||
import ast
|
||||
from pathlib import Path
|
||||
|
||||
from app.chain._contracts import (
|
||||
ChainRuntimeMixinHost,
|
||||
InteractionMixinHost,
|
||||
MusicSubscribeMixinHost,
|
||||
TransferMixinHost,
|
||||
)
|
||||
from app.chain._interaction import InteractionChainMixin
|
||||
from app.chain._messaging import MessageProcessingMixin, NotificationMixin
|
||||
from app.chain._music import MusicSubscribeMixin
|
||||
from app.chain._recognition import RecognitionMixin
|
||||
from app.chain._transfer import (
|
||||
EpisodeFormatMixin,
|
||||
FailedRetryMixin,
|
||||
FileFilterMixin,
|
||||
FileKeyMixin,
|
||||
HistoryMatchMixin,
|
||||
ManualHistoryMixin,
|
||||
ScrapeBatchMixin,
|
||||
)
|
||||
from app.chain.subscribe import SubscribeChain
|
||||
from app.chain.transfer import TransferChain
|
||||
|
||||
|
||||
def test_all_chain_mixins_declare_their_host_protocol() -> None:
|
||||
"""每个存量 Chain mixin 都必须显式声明宿主能力契约。"""
|
||||
expected = {
|
||||
RecognitionMixin: ChainRuntimeMixinHost,
|
||||
MessageProcessingMixin: ChainRuntimeMixinHost,
|
||||
NotificationMixin: ChainRuntimeMixinHost,
|
||||
InteractionChainMixin: InteractionMixinHost,
|
||||
MusicSubscribeMixin: MusicSubscribeMixinHost,
|
||||
FileFilterMixin: TransferMixinHost,
|
||||
ScrapeBatchMixin: TransferMixinHost,
|
||||
EpisodeFormatMixin: TransferMixinHost,
|
||||
HistoryMatchMixin: TransferMixinHost,
|
||||
FileKeyMixin: TransferMixinHost,
|
||||
ManualHistoryMixin: TransferMixinHost,
|
||||
FailedRetryMixin: TransferMixinHost,
|
||||
}
|
||||
|
||||
assert {
|
||||
mixin: mixin.__mixin_host_protocol__ for mixin in expected
|
||||
} == expected
|
||||
|
||||
|
||||
def test_mixin_hosts_provide_injected_chain_factories() -> None:
|
||||
"""具体 Chain 必须提供 mixin 契约要求的链工厂接缝。"""
|
||||
for name in (
|
||||
"_music_media_chain",
|
||||
"_music_download_chain",
|
||||
"_music_search_chain",
|
||||
"_music_site_keywords",
|
||||
"_matches_music_resource",
|
||||
):
|
||||
assert callable(getattr(SubscribeChain, name))
|
||||
for name in (
|
||||
"_transfer_media_chain",
|
||||
"_transfer_storage_chain",
|
||||
"_transfer_subscribe_chain",
|
||||
):
|
||||
assert callable(getattr(TransferChain, name))
|
||||
|
||||
|
||||
def test_domain_mixins_keep_concrete_imports_explicit_until_next_migration() -> None:
|
||||
"""第一阶段先锁定契约标记,具体导入在后续批次逐步下沉到宿主工厂。"""
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
violations = []
|
||||
for relative in ("app/chain/_music.py", "app/chain/_transfer.py"):
|
||||
tree = ast.parse((root / relative).read_text(encoding="utf-8"))
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ImportFrom) and node.module:
|
||||
if node.module.startswith("app.chain.") and node.module != "app.chain._contracts":
|
||||
violations.append(f"{relative}:{node.module}")
|
||||
|
||||
assert set(violations) <= {
|
||||
"app/chain/_music.py:app.chain.download",
|
||||
"app/chain/_music.py:app.chain.media",
|
||||
"app/chain/_music.py:app.chain.search",
|
||||
"app/chain/_transfer.py:app.chain.media",
|
||||
"app/chain/_transfer.py:app.chain.storage",
|
||||
"app/chain/_transfer.py:app.chain.subscribe",
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
"""Ruff 与覆盖率增量门禁测试。"""
|
||||
|
||||
from scripts.architecture.coverage_ratchet import (
|
||||
collect_package_coverage,
|
||||
compare_coverage,
|
||||
)
|
||||
from scripts.architecture.ruff_ratchet import aggregate_diagnostics, compare_counts
|
||||
|
||||
|
||||
def test_ruff_ratchet_rejects_new_rule_and_count_growth() -> None:
|
||||
"""Ruff 基线允许修复,但拒绝新增规则和既有数量增长。"""
|
||||
baseline = {"app/example.py": {"F401": 2}}
|
||||
|
||||
assert compare_counts(baseline, {"app/example.py": {"F401": 1}}) == []
|
||||
assert compare_counts(baseline, {"app/example.py": {"F401": 3}}) == [
|
||||
"app/example.py: Ruff 诊断增长 [F401] 2->3"
|
||||
]
|
||||
assert compare_counts(baseline, {"app/new.py": {"I001": 1}}) == [
|
||||
"app/new.py: 新增 Ruff 诊断 [I001] x1"
|
||||
]
|
||||
|
||||
|
||||
def test_ruff_diagnostics_are_aggregated_by_relative_file_and_code() -> None:
|
||||
"""Ruff JSON 的绝对路径必须归一化为稳定仓库路径。"""
|
||||
from scripts.architecture.ruff_ratchet import PROJECT_ROOT
|
||||
|
||||
path = PROJECT_ROOT / "app" / "example.py"
|
||||
diagnostics = [
|
||||
{"filename": str(path), "code": "F401"},
|
||||
{"filename": str(path), "code": "F401"},
|
||||
{"filename": str(path), "code": "I001"},
|
||||
]
|
||||
|
||||
assert aggregate_diagnostics(diagnostics) == {
|
||||
"app/example.py": {"F401": 2, "I001": 1}
|
||||
}
|
||||
|
||||
|
||||
def test_coverage_ratchet_aggregates_governed_packages() -> None:
|
||||
"""覆盖率门禁只聚合 Application 与 Domain,并按真实语句数加权。"""
|
||||
report = {
|
||||
"files": {
|
||||
"app/application/a.py": {
|
||||
"summary": {"num_statements": 10, "covered_lines": 8}
|
||||
},
|
||||
"app/application/b.py": {
|
||||
"summary": {"num_statements": 30, "covered_lines": 12}
|
||||
},
|
||||
"app/domain/a.py": {
|
||||
"summary": {"num_statements": 20, "covered_lines": 15}
|
||||
},
|
||||
"app/chain/a.py": {
|
||||
"summary": {"num_statements": 100, "covered_lines": 0}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
assert collect_package_coverage(report) == {
|
||||
"application": {"statements": 40, "covered_lines": 20, "percent": 50.0},
|
||||
"domain": {"statements": 20, "covered_lines": 15, "percent": 75.0},
|
||||
}
|
||||
|
||||
|
||||
def test_coverage_ratchet_rejects_only_regressions() -> None:
|
||||
"""包覆盖率达到或超过阈值时通过,任一包下降时失败。"""
|
||||
baseline = {
|
||||
"application": {"percent": 50.0},
|
||||
"domain": {"percent": 75.0},
|
||||
}
|
||||
|
||||
assert compare_coverage(
|
||||
baseline,
|
||||
{"application": {"percent": 50.0}, "domain": {"percent": 76.0}},
|
||||
) == []
|
||||
assert compare_coverage(
|
||||
baseline,
|
||||
{"application": {"percent": 49.99}, "domain": {"percent": 75.0}},
|
||||
) == ["application: 行覆盖率下降 50.00%->49.99%"]
|
||||
@@ -0,0 +1,68 @@
|
||||
"""进程停止契约和 global_vars 兼容边界测试。"""
|
||||
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
from app.runtime.config import GlobalVar
|
||||
from app.runtime.stop import ProcessStopState, runtime_stop_state
|
||||
|
||||
|
||||
def test_process_stop_state_separates_repeatable_workflow_and_one_shot_transfer() -> None:
|
||||
"""工作流停止可恢复,整理路径停止只消费一次。"""
|
||||
state = ProcessStopState()
|
||||
|
||||
state.stop_workflow(7)
|
||||
assert state.is_workflow_stopped(7)
|
||||
state.resume_workflow(7)
|
||||
assert not state.is_workflow_stopped(7)
|
||||
|
||||
state.stop_transfer("/media/a.mkv")
|
||||
assert state.consume_transfer_stop("/media/a.mkv")
|
||||
assert not state.consume_transfer_stop("/media/a.mkv")
|
||||
|
||||
|
||||
def test_system_stop_propagates_to_all_cancellation_scopes() -> None:
|
||||
"""系统停止后所有工作流和整理任务都必须立即观察到停止。"""
|
||||
state = ProcessStopState()
|
||||
|
||||
state.stop_system()
|
||||
|
||||
assert state.is_system_stopped
|
||||
assert state.is_workflow_stopped(99)
|
||||
assert state.consume_transfer_stop("/unknown")
|
||||
|
||||
|
||||
def test_global_vars_stop_api_delegates_to_runtime_contract(monkeypatch) -> None:
|
||||
"""旧 global_vars ABI 必须与新的显式停止状态共享同一事实源。"""
|
||||
event = threading.Event()
|
||||
monkeypatch.setattr(runtime_stop_state, "_system_event", event)
|
||||
legacy = GlobalVar()
|
||||
|
||||
legacy.stop_system()
|
||||
|
||||
assert event.is_set()
|
||||
assert legacy.is_system_stopped
|
||||
|
||||
|
||||
def test_host_code_no_longer_reads_stop_state_from_global_vars() -> None:
|
||||
"""除兼容实现外,宿主不得重新从 global_vars 读取任何停止信号。"""
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
forbidden = (
|
||||
"global_vars.is_system_stopped",
|
||||
"global_vars.stop_system",
|
||||
"global_vars.is_workflow_stopped",
|
||||
"global_vars.stop_workflow",
|
||||
"global_vars.workflow_resume",
|
||||
"global_vars.is_transfer_stopped",
|
||||
"global_vars.stop_transfer",
|
||||
)
|
||||
violations = []
|
||||
for path in (root / "app").rglob("*.py"):
|
||||
if path == root / "app/runtime/config.py" or "app/plugins" in path.as_posix():
|
||||
continue
|
||||
content = path.read_text(encoding="utf-8")
|
||||
for expression in forbidden:
|
||||
if expression in content:
|
||||
violations.append(f"{path.relative_to(root)}:{expression}")
|
||||
|
||||
assert violations == []
|
||||
Reference in New Issue
Block a user