Modules (NXM)
Calendar sources
A package shows its dated records in the nexxus calendar, next to holidays, vacation and the person's own appointments. How the calendar section of the manifest works, who sees which entries, and how moving an entry writes back to the record.
Many records have a date that people plan around: a deadline, an appointment with a patient, a delivery. nexxus has one calendar for that, under StartCalendar. A package does not build its own. It declares calendar sources in its manifest: which records of which entity, by which date fields, for whom, in which colour, and whether people may move them. nexxus reads the records through the regular record search and writes a move through the regular record update, so the package’s rights, validation and events apply as for any edit.
Manifest
The package names entity, date fields, title, people and colours in calendar.
Record search
nexxus asks for the records in the shown days, with the reader's rights.
Calendar
Shows them beside holidays, vacation and appointments, by Mine or All.
Record update
A drag writes the new date back, with the record's validation and the updated event.
The calendar section of the manifest
Section titled “The calendar section of the manifest”calendar is a top-level list. Each entry is one source with its own chip in the calendar.
"calendar": [ { "key": "fristen", "entity": "frist", "label": { "de": "Fristen", "en": "Deadlines" }, "icon": "event_upcoming", "start": "faellig_am", "title": "titel", "subtitle": ["akte", "typ"], "people": ["zustaendig"], "colorField": "typ", "colors": { "notfrist": "red", "frist": "amber", "vorfrist": "teal" }, "filter": { "status": "offen" }, "move": false }]| Field | Required | Meaning |
|---|---|---|
key | yes | Name of the source, unique in the list. A lower-case letter, then lower-case letters, digits, - and _. |
entity | yes | An entity of the package. |
label | yes | The chip’s text, German and English, optionally Polish. |
icon | no | A Material Symbols name. Default: the entity’s icon. |
start | yes | A field of type date (an all-day entry) or datetime (an entry with times), indexed: true. |
end | no | A field of the same type as start, indexed. Without it a date entry lasts one day and a datetime entry 30 minutes. An end before the start counts as missing. |
title | yes | A field of type string, text, enum or ref. An enum shows its label, a ref the display value of its target. Empty: the record’s title. |
subtitle | no | Fields shown smaller under the title, joined with ” · ”. Any type but json and geo. |
people | no | ref fields with target: "core:user". They decide when a record counts as the reader’s own, see below. |
colorField | no | An enum field that colours each entry. |
colors | no | With colorField: value key to a colour. The first one is also the colour of the source’s chip. |
color | no | Without colorField: the colour of the whole source. |
filter | no | A fixed filter on indexed fields: a value, or a list meaning “one of”. The calendar never shows records outside it. |
move | no | true lets people with write access move the entries. Default false. |
The colours are tokens, not hex values, so they work in the light and the dark theme: blue, teal, green, lime, amber, orange, red, pink, purple, slate. A value without an entry in colors, and a source with neither color nor colors, get a token derived from the value or the source key. The derivation is stable: the same key gives the same colour on every server.
Keep legal deadlines and other dates that must not shift by accident at move: false. People still change them on the record page, where the package’s own rules apply.
Who sees what
Section titled “Who sees what”A source appears for a person when the package’s installation is active and the person may read the entity (the permission <module>.<entity>.read). Records carry no rights of their own, so whoever may read the entity sees all of its records that pass the source’s filter. The calendar itself needs the permission calendar.use, which every role with employee rights has.
The reader chooses between Mine and All:
- Mine keeps the records where any of the
peoplefields holds the reader. A record with two people fields (responsible and deputy, say) shows for both. - All shows every record the reader may read. With people chosen in the people filter, the calendar keeps the records where a
peoplefield holds one of them. - A source without
peopleshows only under All without a people filter, because none of its records belongs to anyone.
Dates: a date is a day without a time zone; an all-day entry’s end is included. A datetime is a point in time and shows in the tenant’s time zone (the system setting), so an appointment at 09:30 in Berlin shows at 09:30 for everyone in the tenant. A move writes it back with that zone’s offset.
nexxus asks for the records that start in the days on screen and, with an end, those that began earlier and still run. It reads at most 2000 records per source and request, 200 at a time. A source cut off there is named on the page: there are more entries than the calendar shows at once. A shorter period or a people filter shows them all. If your source can have that many records in a month, add a filter or people.
A click on an entry opens the record page, /x/<module>/<entity>/<id>.
Moving entries
Section titled “Moving entries”With move: true, people who may write the entity (<module>.<entity>.write) drag entries to another day or time, and drag the lower edge of an entry with times to change its end. The AI Assistant moves entries the same way, after the person confirms its card.
nexxus then writes the record through the regular update:
- A move writes
startand, when the record has an end,endwith the same length. A resize writes onlyendand needs anendfield. - Validation runs as on the record page. A
readonlyfield cannot be a moved field; the package check refuses that combination. - The record keeps its history, and the package’s service receives
<entity>.updatedlike for any edit. - The request carries the start the person saw. If the record starts elsewhere by now, nexxus answers 409 with the entry as it is now, and the calendar shows that state with the message Der Eintrag wurde inzwischen geändert, er beginnt jetzt …
Without move: true, or without the write permission, the entry cannot be dragged, and the server refuses a move with 403.
Rules the package check enforces
Section titled “Rules the package check enforces”validatePackage and the upload refuse a package with one message per finding when:
entitydoes not exist, or a named field is not a field of it, or akeyappears twice.startis notdateordatetime, or is not indexed.endhas another type thanstart, is not indexed, or is thestartfield.moveistrueandstartorendisreadonly.titleis notstring,text,enumorref; asubtitlefield isjsonorgeo, or appears twice.- A
peoplefield is not areftocore:user, or appears twice. colorFieldis not anenum, a key incolorsis not one of its values,colorscomes withoutcolorField, orcolorwith it.- A
filterfield is not indexed, has no value, or a value does not fit its type.
The section is new in the platform. A nexxus version without it refuses the manifest because of the unknown field, so set platform to a range that starts at the version that brings the calendar.
Next steps
Section titled “Next steps”- Calendar: what people see and do with your entries.
- Package structure: field types and
indexed. - Data and upgrades: which fields are indexed and what a new version may change.