synology_apm_repo.sdk.units.saas.site module

SiteProvider: M365 SharePoint Site (including document libraries) via list_version_table + item_version_table, built as a SaasWorkloadProvider + NamedGroupRecursiveTree config, wrapped in one extra synthetic level (tree_strategy.CategorizedGroupTree) that splits the root into “Document Library” and “List” groups, keyed as (category, *inner_key). The “List” category node is additionally marked SITE_FLAT_CATEGORY_ATTR (see below).

M365-only — SharePoint has no GWS equivalent (FORMAT-SPEC.md: sharepoint-site). item_version_table has 19 real columns; _ITEM_COLUMNS below reads only the subset this module needs.

Two List shapes, one rule: a “general list” (a data row + optional attachments) and a “document library” (a file or folder) never need a separate lookup to tell apart for content purposes — content addressing always goes through the META object’s own content_list[].object_id, never item_version_table.file_object_id (a write-path punch-hole shortcut only, FORMAT-SPEC.md: sharepoint-site). A row with no attachment (a plain list row, or a document-library folder) has an empty content_list; its own values become its content instead.

Tree: List → Item, grouped by list_id; nested document-library folders additionally use parent-pointer recursion via parent_folder_id within one list — NamedGroupRecursiveTree. item_type encodes SharePoint’s own FileSystemObjectType (numeric File=0/Folder=1, or the string equivalents “FILE”/”FOLDER”).

A document library’s real top level is not always the empty string — list_version_table.root_folder_id is each list’s own real top-level anchor (general lists use ""; document libraries use their own non-empty id). _build_tree reads this per list and passes it to NamedGroupRecursiveTree as root_folder_id_of — without it, a document library’s real (non-empty) top-level anchor would never match the tree’s default empty-string root, and the library would appear empty.

synology_apm_repo.sdk.units.saas.site.SITE_LIST_OVERVIEW_ATTR = 'site_list_overview'

Marks exactly a plain List’s own group node (never the root, a category, or a document-library group) — the browser’s unit_screen.py reads this via is_list_overview to (a) render the node as a non-expandable tree leaf (this List’s own items are never individually tree-navigable — a spreadsheet-style overview of them is enough) and (b) build that overview by reading the items directly through the provider instead. A named constant (and is_list_overview below), not a bare string literal read independently at each of the browser’s own call sites, so a typo on either side is a real NameError/ImportError instead of a silent “always False.”

synology_apm_repo.sdk.units.saas.site.SITE_FLAT_CATEGORY_ATTR = 'site_flat_category'

Marks exactly the site root’s own “List” category node (never an individual List, a document-library group, or the root itself) — the browser reads this via is_flat_category to hide every individual List from the folder tree (no recursion into this node’s own children for tree purposes) while still listing them as ordinary file-table rows, same as any other folder’s children. Unlike SITE_LIST_OVERVIEW_ATTR, this node stays perfectly ordinary for selection/navigation purposes — only the tree-expansion decision changes.

synology_apm_repo.sdk.units.saas.site.is_list_overview(node)

Whether node is a plain List’s own group node — see SITE_LIST_OVERVIEW_ATTR.

synology_apm_repo.sdk.units.saas.site.is_flat_category(node)

Whether node is the site root’s own “List” category node — see SITE_FLAT_CATEGORY_ATTR.

synology_apm_repo.sdk.units.saas.site.SITE_CONFIG = SaasWorkloadConfig(root_name='Lists', leaf_kind=<UnitKind.SITE_ITEM: 'site_item'>, tables=('list_version_table', 'item_version_table'), tree_factory=<function _build_tree>, assemble=<function _assemble>, object_names={'list_version_table': ('site_list_db',), 'item_version_table': ('site_item_db',)}, extra_attrs=<function _item_extra_attrs>, group_attrs=<function _group_attrs>, leaf_size=<function _leaf_size>)

SaasWorkloadConfig behind SiteProvider — Lists/document libraries via tree_strategy.CategorizedGroupTree.

async synology_apm_repo.sdk.units.saas.site.SiteProvider(repo, version, saas_streams, *, shared=None)

Constructor-style factory over SITE_CONFIG — callable exactly like a constructor (await SiteProvider(repo, version, saas_streams)), resolving the service DB via the connector’s own object-name index only, never a scan. shared is accepted only for calling-convention uniformity with units/dispatch.py’s _ProviderFactory — SITE never offers more than this one candidate, so it is always None in practice.