diora-web/docs/projects.md

97 lines
5.6 KiB
Markdown
Raw Permalink Normal View History

# Projekte
Projects of a preset: the first is **Forschung** (a research project: sources, citations,
notes; Radar and Schreiben follow). In the navigation (`nav.js`, section and group `projekte`,
flag `side`): a tab beside Home · Lesen · Hören on a phone, at the foot of the sidebar and of
the wide bar above Suche · Abos & Quellen. The search moved out of the phone's tab bar: a
magnifier in the bar on top (`suche` is a footer section; the apps' section bars show it).
## End-to-end encrypted
Like the books (docs/library.md): a project's data (`{name, description}`) and every item's
data are AES-GCM blobs with the user's key (`32-crypto.js`, iv hex, ciphertext base64). The
server stores them and knows only: a project exists, its preset, archived, and what an item
points to — `kind` + `ref` (a book's, episode's or article's id, never its title).
## Items
| kind | ref | data |
|---|---|---|
| `paper` | – | `{key, csl, note, doi}` (CSL-JSON from doi.org) |
| `book` | book id | `{key, csl, note, type}` (CSL from the book's meta) |
| `episode` | episode id | `{key, csl, note, podcast, feed, position}` (position: seconds, "ab 12:34") |
| `article` | feeds item id | `{key, csl, note}` |
| `note` | – | `{title, body (Markdown), folder}` |
A book, episode or article is in a project once (adding again answers `existing: true`).
`key` is the citation key for `[@key]` / `[@key, S. 12]` in notes: first author's family name
(or the podcast's), year, first word of the title — unique in the project, editable.
Notes: Markdown (headings, lists, quotes, bold/italic, links); the view shows citations as
"(Amodio & Jost 2007, S. 3)" and a list of the works cited. Saved as one types (0.9 s).
Export: BibTeX and CSL-JSON of the sources (all or the chosen kind).
## Linking from elsewhere
`DioraProjects.link(kind, ref, info)` opens the sheet "Mit Projekt verknüpfen" (the projects,
the ones it is in ticked, + Neues Projekt). Called from the book sheet (library, apps), the
article reader (◇ in its bar), the episode sheet and the player (apps, native-podcast.js).
`DioraProjects.of(kind, ref)` → `[{id, name}]` the projects it's in; `onChange(fn)` after changes.
## Desktop: a window of its own
The project's menu (⋯) has "In neuem Fenster öffnen" when `dioraDesktop.openWindow` is there:
the desktop opens the page with `?project=<id>`; `projects.js` then shows only that project
(`html.prj-solo` hides the navigation and the dock).
## Writing and conflicts
Every write sends `base_iv` (the IV it changed). Changed elsewhere since: 409 with the current
state. A note's text then goes beside it as a copy "(Konflikt)"; other data reloads.
## API (signed in)
- `GET /projects/` → `{projects: [{id, preset, data_ct, data_iv, archived, position, items, …}], links: [{project, kind, ref}], presets}`
- `POST /projects/create/` `{preset, data_ct, data_iv}` → `{project}`
- `GET /projects/<id>/` → `{project, items: [{id, kind, ref, data_ct, data_iv, created_at, updated_at}]}`
- `POST /projects/<id>/` `{data_ct, data_iv, base_iv}` and/or `{archived}` / `{position}`
- `POST /projects/<id>/delete/`
- `POST /projects/<id>/items/add/` `{kind, ref?, data_ct, data_iv}` → `{item, existing}`
- `POST /projects/items/<id>/` `{data_ct, data_iv, base_iv}` → `{item}` (409 `{item}` when stale)
- `POST /projects/items/<id>/delete/`
- `GET /projects/doi/?q=<DOI | doi.org link | arXiv link or id>` → `{doi, csl}` — fetched from
doi.org (Crossref, DataCite …) as CSL-JSON, cached a week, nothing else kept.
## Radar
A project can have a Radar (`projects/radar.py`, `projects/papers.py`): every week the new papers
from PubMed, arXiv, bioRxiv and medRxiv, sorted by Claude into the config's groups (the first
one — "lesenswert" — with what it's about, how solid it is, the political hook), the week's
news (web search), a basic term explained. One Claude batch (Opus, half price): about 0.40 $
a week. Ported from the "Neuropolitik Grundlagen" session's `F:
europolitik ools`
(fetch_papers.py, digest_batch.py); the digest is their bundle format (version 1).
- Config per radar (`Radar.config`, presets in `projects/radar_presets.py`): PubMed queries per
topic, arXiv query, keyword pattern for the preprint servers, groups and their labels, the
prompts, weekday and hour (Europe/Berlin), days. **Plain on the server**: it searches with them.
The papers and digests are public material, plain too (`RadarDigest.bundle`).
- The decisions (gelesen / später / verworfen / in Quellen) are the user's: an encrypted item
of kind `radar` (`{decisions: {paper id: state}}`). "→ Quellen" makes a `paper` source
(citation data from doi.org when there's a DOI, else from the record).
- Runs from the host's crontab every half hour: `docker exec diora-prod python manage.py radar`
(submits what is due, collects finished batches). Needs `ANTHROPIC_API_KEY` in the container.
`radar --setup <project> neuropolitik` gives a project its Radar; `radar --import <project>
<file>` takes a digest made elsewhere; `radar --seen <project> <file>` ids reported before.
- API: `GET /projects/<id>/radar/` → `{radar: {enabled, title, groups, group_labels, weekday,
hour, days, sources, running, submitted, last_run_at, last_error, next_run, key}, digests:
[{id, generated, bundle}]}` (the latest 12); `POST …/radar/settings/` `{enabled}`;
`POST …/radar/run/` (fetch at the next cron run); `POST …/radar/import/` (a bundle, e.g.
`digest_batch.py --diora-url`).
## Next
Papers as books (a paper's PDF into the library, its highlights
into the project's notes), Schreiben (drafts with the bibliography in a citation style),
the projects in the search, more presets.