68 lines
3.5 KiB
Markdown
68 lines
3.5 KiB
Markdown
# Licenses
|
||
|
||
The license vocabulary: data model, seeding, legal text files and API. For
|
||
the user-facing overview see the [User guide](../user/licenses.md).
|
||
|
||
## Data model
|
||
|
||
Licenses are a controlled vocabulary (table `licenses`, model
|
||
`App\Models\Lists\License`), created and populated at install time by the
|
||
`LicenseSeeder` — **not** by the v1 ETL.
|
||
|
||
| Column | Meaning |
|
||
|---|---|
|
||
| `name` | Official full name (e.g. *Attribution 4.0 International*) |
|
||
| `acronym` | Display label shown in the UI (e.g. *CC BY 4.0*) |
|
||
| `spdx_id` | [SPDX](https://spdx.org/licenses/) identifier for export and interoperability; `NULL` for entries outside the SPDX License List — never invent one |
|
||
| `kind` | Backed enum `App\Enums\LicenseKind`: `license`, `mark` or `rights_statement` |
|
||
| `description` | One-sentence explanation shown in the forms |
|
||
| `uri` | Canonical URI (creativecommons.org / rightsstatements.org), also used in the Linked Art JSON-LD |
|
||
| `file` | File name of the legal text bundled in media download zips; `NULL` where no legal text exists |
|
||
| `for_record` / `for_media` | Scope flags: records only accept open licenses (CC0, CC BY), media accept everything |
|
||
| `sort_order` | Ordering in selects, from the most open to the most restrictive |
|
||
| `active` | Soft retirement: an inactive license disappears from forms but stays valid for content already using it |
|
||
|
||
Scope and `active` filtering happens in the form selects **and** is
|
||
re-validated server side; an edit form must still include the currently
|
||
assigned license even when it is inactive or out of scope.
|
||
|
||
## Seeding and legacy ids
|
||
|
||
The seeder ships 11 entries: Public Domain Mark + the CC 4.0 family + the
|
||
three most common rights statements (*InC*, *InC-EDU*, *CNE*). Ids **1–3 are
|
||
fixed** and match the legacy v1 database (1 = PDM, 2 = CC0, 3 = CC BY) so the
|
||
ETL maps artifact/media foreign keys 1:1 without translation. Further entries
|
||
can be added by administrators at runtime.
|
||
|
||
## Legal texts and downloads
|
||
|
||
The official CC legal texts live in
|
||
**`backend/storage/app/public/licenses/`**, named after their SPDX id
|
||
(e.g. `CC-BY-4.0.txt`). They are versioned in the repository — an exception
|
||
in `storage/app/public/.gitignore` — so they exist from the first clone. From
|
||
there the backend bundles them into media download zips, and the frontend can
|
||
link them directly (`/storage/licenses/…`, via `php artisan storage:link`).
|
||
Marks and rights statements have no legal text (`file` is `NULL`): the zip
|
||
only carries their canonical URI.
|
||
|
||
!!! warning "REUSE"
|
||
The root `LICENSES/` directory is reserved for the licenses **of the
|
||
repository**: [REUSE](https://reuse.software) fails the lint on license
|
||
texts not referenced by any file ("unused license"), and duplicate SPDX
|
||
file names anywhere under `LICENSES/` crash the tool. That is why the
|
||
downloadable texts live under `backend/storage/`. Their provenance is
|
||
annotated in `REUSE.toml`: Creative Commons dedicates the text of its
|
||
licenses to the public domain (CC0), which is also why `LICENSES/`
|
||
contains `CC0-1.0.txt`.
|
||
|
||
## API
|
||
|
||
| Endpoint | Access | Purpose |
|
||
|---|---|---|
|
||
| `GET /api/licenses` | public | list; filters `scope=record\|media`, `active=0\|1` |
|
||
| `GET /api/licenses/{id}` | public | detail |
|
||
| `GET /api/licenses/{id}/usage` | authenticated | is the license in use? |
|
||
| `POST /api/licenses` | admin | create an entry |
|
||
| `PUT/PATCH /api/licenses/{id}` | admin | update (partial updates supported, e.g. only `active`) |
|
||
| `DELETE /api/licenses/{id}` | admin | delete; blocked with `409` when the entry is in use |
|