postulo-dav: company contacts to CardDAV and interviews to CalDAV, in both directions #16

Closed
opened 2026-09-05 12:29:14 +00:00 by tiagoagueda · 0 comments
Owner

Observation

postulo-dav - ability to read / write company contacts and read/write interview meetings

Shape

  • A separate package, postulo-dav, one connection (#11): server URL, username, password or app password (secret), and the collections found by discovery (RFC 6764: /.well-known/carddav and /.well-known/caldav). One implementation serves Nextcloud, Radicale, Baïkal, SOGo, Fastmail, iCloud and the rest, because they speak the same standards — CardDAV (RFC 6352) and CalDAV (RFC 4791).
  • Dedicated collections. The plugin creates, or the person picks, an address book Postulo and a calendar Postulo, and only those are in scope. A personal address book holds hundreds of people with nothing to do with the job hunt; "sync everything" would import a family into a job tracker. What the person wants is the recruiters and the interviews on the phone, and that is what this does.
  • Contacts ↔ vCard 4.0 (RFC 6350): FN/N ← name, ORG ← company, TITLE ← role, EMAIL, TEL, URL ← LinkedIn, NOTE ← notes. The vCard UID and the server's ETag are kept on a side table (SyncLink: connection, local object, remote href, UID, ETag, last synced), never on the Contact itself.
  • Interviews ↔ VEVENT (RFC 5545): DTSTART/DTEND, SUMMARY "Interview: Role at Company", LOCATION or URL, DESCRIPTION with the preparation notes and the application's link, ATTENDEE for contacts with an email address — informational only: Postulo does not send invitations, iTIP scheduling is out of scope — and a VALARM from the linked reminder. Needs #14.
  • Both directions. Push on local change, through the tasks framework; pull on a schedule, with sync-collection (WebDAV-Sync, RFC 6578) where the server offers it and CTag/ETag comparison otherwise. Conflicts: the later change wins and the losing version is kept as a timeline note ("changed on the phone: …"). Remote deletion never deletes locally: the record is unlinked and flagged. A swipe on a phone must not erase an interview record.
  • Libraries. httpx (already a dependency) for WebDAV; vobject (Apache-2.0) to read and write vCard and iCalendar; a dedicated CalDAV client library only if its licence and maintenance are acceptable.
  • Scheduling. Pulling needs the periodic runner #4 settles on.

Classification

Enhancement. A separate package; not breaking.

Depends on

  • #11 — connection and secrets
  • #14 — there is nothing to put in a calendar until interviews exist
  • #4 — the scheduler for periodic pulls

Open questions

  1. One connection with two collections (proposal) or a connection per protocol?
  2. A read-only mode for people who only want the calendar to show interviews and never write back?
  3. Recurring events on pull: interviews do not recur; propose ignoring RRULE rather than expanding it.
  4. Contacts created on the phone in the Postulo address book with no company: land them on a "(no company)" holding company, or wait until the person assigns one?
## Observation > postulo-dav - ability to read / write company contacts and read/write interview meetings ## Shape - **A separate package, `postulo-dav`**, one connection (#11): server URL, username, password or app password (secret), and the collections found by discovery (RFC 6764: `/.well-known/carddav` and `/.well-known/caldav`). One implementation serves Nextcloud, Radicale, Baïkal, SOGo, Fastmail, iCloud and the rest, because they speak the same standards — CardDAV (RFC 6352) and CalDAV (RFC 4791). - **Dedicated collections.** The plugin creates, or the person picks, an address book *Postulo* and a calendar *Postulo*, and only those are in scope. A personal address book holds hundreds of people with nothing to do with the job hunt; "sync everything" would import a family into a job tracker. What the person wants is the recruiters and the interviews on the phone, and that is what this does. - **Contacts ↔ vCard 4.0** (RFC 6350): `FN`/`N` ← name, `ORG` ← company, `TITLE` ← role, `EMAIL`, `TEL`, `URL` ← LinkedIn, `NOTE` ← notes. The vCard `UID` and the server's `ETag` are kept on a side table (`SyncLink`: connection, local object, remote href, UID, ETag, last synced), never on the `Contact` itself. - **Interviews ↔ VEVENT** (RFC 5545): `DTSTART`/`DTEND`, `SUMMARY` "Interview: Role at Company", `LOCATION` or `URL`, `DESCRIPTION` with the preparation notes and the application's link, `ATTENDEE` for contacts with an email address — informational only: Postulo does not send invitations, iTIP scheduling is out of scope — and a `VALARM` from the linked reminder. Needs #14. - **Both directions.** Push on local change, through the tasks framework; pull on a schedule, with `sync-collection` (WebDAV-Sync, RFC 6578) where the server offers it and CTag/ETag comparison otherwise. Conflicts: the later change wins and the losing version is kept as a timeline note ("changed on the phone: …"). **Remote deletion never deletes locally**: the record is unlinked and flagged. A swipe on a phone must not erase an interview record. - **Libraries.** `httpx` (already a dependency) for WebDAV; `vobject` (Apache-2.0) to read and write vCard and iCalendar; a dedicated CalDAV client library only if its licence and maintenance are acceptable. - **Scheduling.** Pulling needs the periodic runner #4 settles on. ## Classification Enhancement. A separate package; not breaking. ## Depends on - #11 — connection and secrets - #14 — there is nothing to put in a calendar until interviews exist - #4 — the scheduler for periodic pulls ## Open questions 1. One connection with two collections (proposal) or a connection per protocol? 2. A read-only mode for people who only want the calendar to *show* interviews and never write back? 3. Recurring events on pull: interviews do not recur; propose ignoring `RRULE` rather than expanding it. 4. Contacts created on the phone in the *Postulo* address book with no company: land them on a "(no company)" holding company, or wait until the person assigns one?
tiagoagueda added this to the 0.2.0 milestone 2026-09-05 12:29:14 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
Postulo/postulo#16
No description provided.