|
| 1 | +# litfetch |
| 2 | + |
| 3 | +litfetch resolves a scholarly article identifier to its retrievable files — |
| 4 | +full-text body and supplementary material — and fetches their bytes. It owns |
| 5 | +*what an article's files are and how to fetch them*; it does not own *where a |
| 6 | +consumer stores them* nor *how they are rendered* (e.g. XML → markdown). |
| 7 | + |
| 8 | +## Language |
| 9 | + |
| 10 | +### Identity |
| 11 | + |
| 12 | +**Article**: |
| 13 | +A scholarly paper litfetch retrieves, identified by an `ArticleIds` bundle. |
| 14 | +*Avoid*: paper, document, work, record (a `record` is the consumer's cached wrapper). |
| 15 | + |
| 16 | +**ArticleIds**: |
| 17 | +The immutable identity bundle — any of `pmid`, `pmcid`, `doi`. A thin record; |
| 18 | +resolvers enrich it, sources consume whichever identifier they `require`. |
| 19 | +*Avoid*: identifiers, keys, ids. |
| 20 | + |
| 21 | +### The file-set |
| 22 | + |
| 23 | +**File-set**: |
| 24 | +The collection of files that make up a retrieved article — the body and any |
| 25 | +supplementary material, in each of the forms (media types) they are available |
| 26 | +in. The unifying model litfetch owns and a consumer de/serialises. |
| 27 | +*Avoid*: assets, contents, bundle (a bundle is `ArticleIds`). |
| 28 | + |
| 29 | +**File**: |
| 30 | +One file in the set — a body rendition or a supplementary item, in one media |
| 31 | +type, with a known `source`, `media_type`, `size`, and an upstream location. The |
| 32 | +single ref type; supersedes the former split between `AlternateRepresentation` |
| 33 | +and `SupplementaryFile`. |
| 34 | +*Avoid*: representation, rendition, supplementary file, artifact (a `RawArtifact` |
| 35 | +is a File once its bytes are in hand). |
| 36 | + |
| 37 | +**Body**: |
| 38 | +The file-set member that is the article full text itself — the file a consumer |
| 39 | +renders (e.g. to markdown). Distinct from supplementary material. |
| 40 | +*Avoid*: main file, primary document. |
| 41 | + |
| 42 | +**Supplementary**: |
| 43 | +A file-set member that is *additional* material — figures, datasets, tables — |
| 44 | +not the article body. |
| 45 | +*Avoid*: supplement, attachment, extra. |
| 46 | + |
| 47 | +### Sourcing |
| 48 | + |
| 49 | +Every File is hosted upstream (PMC, a publisher). litfetch holds its `uri`, |
| 50 | +owning `source`, and the `credential_key` a fetch needs. The consumer cannot |
| 51 | +construct these — only litfetch knows the upstream layout and auth. |
| 52 | +*Avoid*: remote file, hosted ref, source file. |
| 53 | + |
| 54 | +### Metadata |
| 55 | + |
| 56 | +**Source metadata**: |
| 57 | +Facts about *access and provenance* that litfetch owns: the owning `source`, the |
| 58 | +upstream `uri`, the `credential_key` required, and the **licence** / access |
| 59 | +terms under which the file may be used. Licence carries a **basis** — |
| 60 | +*extracted* from the fetched bytes (JATS `<license>`, Elsevier |
| 61 | +`openaccessUserLicense`; authoritative for exactly those bytes) or *asserted* by |
| 62 | +an external access authority (Unpaywall) when the bytes carry none (a PDF). |
| 63 | +litfetch returns the licence raw; mapping to an SPDX id is the consumer's. |
| 64 | +*Avoid*: provenance metadata, access info. |
| 65 | + |
| 66 | +**Bibliographic metadata**: |
| 67 | +Descriptive facts about the article — title, authors, journal, date. |
| 68 | +**Out of litfetch's scope entirely**: it neither owns the shape nor surfaces the |
| 69 | +raw provider results, even though its resolvers' API calls return such fields. A |
| 70 | +consumer that wants bibliographic data calls the provider APIs itself (it |
| 71 | +controls the scoping) and feeds the resulting identifiers to litfetch. See the |
| 72 | +boundary below. |
| 73 | +*Avoid*: citation, bib data, article metadata. |
| 74 | + |
| 75 | +## Ownership boundary |
| 76 | + |
| 77 | +The seam between litfetch and its consumers. Data flows *through* litfetch |
| 78 | +because the consumer can neither construct the file refs (they need upstream |
| 79 | +URLs and per-source auth) nor fetch their bytes without it. |
| 80 | + |
| 81 | +**litfetch owns**: identity (`ArticleIds`); the File-set model; the act of |
| 82 | +fetching (uri + credential routing per source); source metadata and license; and |
| 83 | +the canonical structural de/serialisation of all of these (a backend-agnostic |
| 84 | +dict mapping — not a wire format). |
| 85 | + |
| 86 | +**The consumer owns**: placement — filesystem/store layout, blob storage, |
| 87 | +record `status`, leases — the *shape* of bibliographic metadata, and *rendering* |
| 88 | +(turning a fetched body into markdown or other derived forms). |
| 89 | + |
| 90 | +**litfetch is not a bibliographic-metadata client**: resolvers return only |
| 91 | +`ArticleIds` and stay that way — litfetch will not surface the bibliographic |
| 92 | +fields S2/NCBI return, even raw. Doing so would force litfetch to fix each |
| 93 | +provider call's scope (e.g. S2's `fields=`) and thereby dictate what is fetched; |
| 94 | +the only coherent alternative is consumer-controlled scoping, but a consumer in |
| 95 | +control of those calls can resolve identifiers itself and hand them to litfetch |
| 96 | +directly. So litfetch touches provider APIs for three purposes only — completing |
| 97 | +identifiers, fetching files, and resolving **access terms** (licence / OA status |
| 98 | +via Unpaywall, which is access metadata, not bibliographic) — and surfaces only |
| 99 | +their results. Bibliographic fields stay out of scope. |
0 commit comments