Put companies, departments and the person's own card on the plugin surface, with services to write companies, departments, contacts and their rows #328
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#328
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
postulo.plugins.apihands out the recordsApplication,Contact,Interview,SuggestionandSyncLink; its writes are the timeline and interview calls,suggest,record_listing_event,get_or_create_company(by name or Wikidata id), and helpers for a holder's primary number or link only. The DAV improvements ask to pair a card "to the user, to a person, to a department, or to a company" (the user read here as the account holder, whose details areUserandProfile; postulo/postulo-dav#8 settles that reading), to import one "as a new company (or update existing one)", and to export from Postulo. None of that can be written against the surface, and postulo-dav'stests/test_surface.pyfails any import past it.What is missing today
Companyis not on the surface (src/postulo/plugins/api.py), and no service writes itswebsite,careers_url,location,notes,kindorparent: the API sets attributes and saves (add_company,patch_companyinsrc/postulo/api/routers/companies.py).Department, a name under a company (src/postulo/jobs/models.py), is not on it; only the contact form and the archive import create one (src/postulo/jobs/forms.py,src/postulo/core/importer.py).Contact.objects.createandcontact.save()(postulo-dav,src/postulo_dav/sync.py), against Writing a plugin's "Never write by saving a model"; the API'sadd_contactdoes the same.save_phone_numberandsave_web_linkedit the primary row and touch nothing else (src/postulo/core/phone_numbers.py,src/postulo/core/web_links.py). No surface call reaches the other rows, and only the profile page's formset saves a postal address (src/postulo/core/postal.py).contact_details(owner)insrc/postulo/documents/rendering.pyassembles them, but for a CV header: one number, no address.Proposal
Read:
CompanyandDepartment, scoped withfor_user(), and the vocabularies a card maps onto:CompanyKindand the kinds of telephone number and postal address.numbers_for,links_for).contact_details: given and family name, the sign-in address, headline, location, picture (Profile.picture), and their numbers, addresses and links as above.Write, each with a keyword
actor, taking the owner from the record handed in where there is one, asrecord_listing_eventdoes, and refusing another owner's record:update_company: name, website, careers page, location, notes, kind, parent. A name another of the person's companies has is refused (unique_company_name_per_owner), never merged (#239).get_or_create_department(company, name).create_contactandupdate_contact, runningContact.clean, so a department of another company is refused.save_phone_numbers,save_postal_addresses,save_web_links: make a holder's rows these, keeping a row that stays and settling one primary. A row the uniqueness rules refuse comes back with the reason instead of raising, and hearing it spends the #142 allowance as a form does. With a switch off, only the primary is written, assave_phone_numberdoes today.Identifiers stay off (
set_identifiersincluded): RFC 6350 has no property for a registry number, a Wikidata id or an ORCID iD.The names are proposals. Each needs its line in Writing a plugin (
tests/test_wiki_surface.py), a test intests/test_plugin_surface.pyand a changelog line; the published check inpostulo.plugins.testingcompares imports with the surface module itself and needs no change.Decisions
User.email, unique), a verified number or the recovery number (#142, #144). The alternative is the importer's rule, fill blanks and never overwrite (Record.personinsrc/postulo/resume/importing.py), still leaving those three alone, and can come later.postulo.plugins.email_addresses), some kept as a way back in rather than to give out.actorrecords.actoris a column only onApplicationEventandListingEvent; companies, departments and contacts have no history. Recommended: take it now, so the signature lasts, and record nothing with it until these records have a history of their own. The alternative is a line in the record's notes.src/postulo/jobs/structure.py). Recommended: reads work either way; creating a department, putting a contact in one or setting a parent is refused, so a sync cannot build what the person is not shown. The alternative lets a phone fill in a structure nobody sees until the feature is back.Needed by
postulo/postulo-dav#8, postulo/postulo-dav#9 and postulo/postulo-dav#10. A company holds numbers and addresses only once #329 lands; until then the row services take a contact.
Done when
postulo.plugins.apican read a company, its departments and the person's card; update a company; create a department and a contact; and write several numbers, addresses and links.Contact.objects.createandcontact.save()can go; the API'sadd_contactuses the same service.UserorProfile. A test each.From the list of DAV plugin improvements of 2026-09-30.