github ulsklyc/yuvomi v2.68.0

4 hours ago

Added

  • A wall tablet can now tick a task off and ask for a reward, for whoever is standing in front of
    it.
    Until now a display only showed things. Tapping a task on a tablet opens the list of people
    and asks who did it, because on a wall "me" is nobody; picking someone ticks the task off and
    records that person as having done it, so the points go where the work went. On the rewards page
    each person keeps their own button for asking to redeem something, and the tablet is recorded as
    having asked. Those two are everything a display can do: it still creates nothing, edits nothing,
    deletes nothing, and changes no settings, and it cannot undo a tick either, because taking one back
    gives points away again and that stays with the household. A person who is not allowed to tick
    tasks off is not offered on the tablet, and a task that is not visible to the whole household does
    not appear there and cannot be ticked off through it. Whether a redemption still needs approval is
    unchanged: the display asks, it never approves.

  • A wall tablet can get an account of its own that only a paired device can use. Under Settings an
    administrator creates a display, gets a ten-character pairing code, and types it in once on the
    tablet; from then on the tablet shows the dashboard, calendar, tasks and rewards, and nothing else.
    A display is not a household member: it appears in no list of people, cannot be assigned anything,
    and is never offered as a person. It has no usable password and cannot sign in with a username and
    password or through SSO, so nobody has to type a household password on a device that hangs on a
    wall and nobody ever signs out of. It reads household-visible entries only, never anybody's private
    ones, and it can only read - ticking off and requesting a redemption come later (#1209). The
    pairing code is valid once and for fifteen minutes, the credential lands in an httpOnly cookie that
    no script on the page can read, and it stays valid until an administrator revokes it - with "last
    seen" beside it, so revoking is an informed decision rather than a guess. Revoking takes effect on
    the device's next request. (#1208)

  • Ticking a task off can now name who did it, not just who tapped the checkbox. A small person
    button sits next to the checkbox and opens the list of household members; picking one marks the
    task done and records that person as having done it. The checkbox itself is untouched - one tap,
    exactly as before - and the button only appears where it answers something, so a household of one
    never sees it and a task that is already done or filed away does not offer it. The completion now
    keeps both people: who ticked it off, as always, and who did it. The history shows the person who
    did the work, notes "ticked off by ..." beside it when the two differ, and its person filter
    follows the displayed name, so filtering and display can no longer disagree. Points follow the
    same answer: a named member who takes part in rewards receives them instead of the assignees, and
    a named member who does not take part means no points at all rather than crediting somebody the
    record just said did not do the work. Undoing a completion still withdraws exactly what it booked,
    whoever received it. Nothing changes without the new button: leave it alone and the history shows
    you, the assignees rule applies, and existing entries are left exactly as they were - they are not
    backfilled with a claim nobody ever made. PATCH /api/v1/tasks/{id}/status takes an optional
    done_by_user_id for this; it has to be a household member, and it only applies to the transition
    into done. (#1205)

  • Fasting insights summarize completed records and captured goals. Calendar windows,
    interval-based streaks, weekly actual/goal values, and history/CSV date filters use the
    household display time zone consistently. Calculations remain bounded for very long intervals.
    (#1178)

  • Health has a new Prevention tab for vaccinations and check-ups. Define your household's own
    types (a tetanus booster, a dentist check-up, anything) with an optional recurring interval -
    there is no shipped catalog, since regional vaccination schedules go stale. Log what happened and
    when, and the tab shows a "due / overdue" list computed from your most recent entry per type. A
    caregiver logging for the person they care for follows that person's own visibility default, not
    their own. Caregivers also receive the due reminder themselves, subject to the owner's opt-in - it
    names the person it is about, so it stays useful to someone caring for more than one family
    member - and revoking a caregiver's access removes that reminder immediately. The type registry is
    admin-editable under Settings → Modules → Health.

  • Family documents can now carry an optional expiry date and reminder lead time. Set an expiry
    (e.g. a passport or a residence permit) and how many days ahead to be reminded - an expiring or
    overdue document shows a status chip, and a matching "expiring soon" filter chip sits next to the
    category chips. Archiving a document (or deleting it) clears its reminder, so an archived scan
    never keeps nagging.

  • Fasting can now remind you when you reach your goal and when it is time to start again.
    Each reminder can be enabled independently. Changing a fast, its goal or its permissions removes
    notifications that no longer apply without erasing the saved preference. (#1179)

Changed

  • The jump-to-now reset sits behind the period stepper in all three period-navigation headers,
    and hides while the current period is on screen
    (#1164). Calendar, Meals, and Budget each reset
    their period a different way: Calendar's "Today" stood before the arrows, Meals' "Today" lived far
    from its stepper among the content actions next to "Randomize plan" - and dropped onto a second
    row, detached from the week it resets, on narrow screens - and only Budget had it right, behind
    the stepper, where its code records the rule: a reset is not a navigation step. Calendar and Meals
    now follow that rule; Budget's position is untouched. Visibility follows Calendar's rule
    everywhere: the reset is hidden while the current period is displayed - a button that silently
    does nothing on the current week or month tells a screen-reader user about a control that has no
    effect - and it keeps its slot: hiding it now toggles visibility and inert on a class, not the
    hidden attribute, so its box stays in the layout and the arrow next to it never moves, whether
    the reset is showing or not. Toggling the reset's own visibility no longer changes header height
    at any width by itself; a header can still change height between two periods for reasons that
    have nothing to do with this reset (a label whose text wraps differently at very narrow widths,
    for one, on both this branch and main), and that is unchanged by this fix. Below 640px, Meals'
    reset additionally loses its visible word and becomes an icon-only button, the same width the two
    arrows already use; the word survives only on aria-label/title, not visually.

Fixed

  • An installation that is interrupted during its very first start comes back up on its own.
    An empty database file stops Yuvomi from starting, which is right for every way such a file
    comes about but one: with DB_ENCRYPTION_KEY set, creating the database file and writing
    its first page lie about 150 milliseconds apart, because the key is derived in between, and a
    first start that was killed in that window left exactly one empty file behind. The next start
    then refused, and somebody had to delete that file by hand before the installation could finish -
    no data was lost, but an install interrupted at the wrong moment did not come back up by itself.
    A new database is now created beside its final place, as <DB_PATH>.creating, and moved into
    place only once it is a database. An interrupted first start therefore leaves only that working
    file, which the next start picks up again, and the database file itself is either absent or
    complete, never empty. (#1287)

  • Moving things into the shopping list now needs shopping rights, in both directions. Sending a
    meal or a recipe to a shopping list writes into the shopping module, but it was judged by the
    module the button sits in: a member with meal-plan access and no shopping access could fill a
    list they cannot even open, and an API token scoped to the meal plan could do the same. The other
    direction had the same gap - importing the meal plan into a shopping list marks those ingredients
    as transferred, which is meal-plan data, so read-only access to the meal plan was enough to
    change it. Each of these now asks for write access to the module it writes into, whichever page
    or token the request comes through, and answers a missing right the same way the rest of the app
    does. Undoing a transfer follows the same rule, but only where it touches the meal plan: taking
    back a pantry or recipe transfer still works with shopping rights alone. Anybody who has both
    rights notices no difference. The buttons themselves are still offered for now; hiding them comes
    with the read-only work on the kitchen pages. (#1290)

  • A recurring appointment moved "from this date on" in another calendar no longer appears twice on
    that day.
    When a series is split that way, the other calendar ends the old series and starts the
    new one at the split - and Open-Xchange (mailbox.org), for one, ends the old series one second
    before the appointment on the split day itself, not on the day before. Yuvomi read only the date
    from that end marker and threw the time away, so the old series still produced its appointment on
    the split day while the new one already began there: that single day showed both times, every
    other day was correct. The end of a series is now read as the moment it is. A series that ends on
    a whole day keeps it, so all-day series are unchanged - and so is every split Yuvomi itself
    makes, which has always ended the old series on the day before. Subscribed ICS calendars are read
    the same way. (#1269)

  • A member no longer gets push notifications from a module they are not allowed to use. Taking a
    module away from someone already removed its reminders from the in-app list, but the push
    notification and any notification channel kept going out: the task title, the subscription name
    with its amount and renewal date, the document name with its expiry date - and tapping one opened
    a page that turned the person away. Reminders of a module somebody may no longer use now stay
    silent on every route. The reminder is always one that person set or was given, so nothing ever
    crossed over to somebody else's data; what was missing was the case "the permission was taken away
    after the reminder already existed". Read access is not a lock: whoever may read a module still
    hears from their reminders, and an administrator is unaffected. The reminders are held back rather
    than deleted, because a permission can be given back - once it is, the ones that fell due in the
    meantime arrive, as they would after the server had been down for a while. (#1289)

  • A reminder set for a single occurrence of a repeating event now arrives at the time it says.
    Changing the reminder of one occurrence ("Only this event" or "This and following") stored the
    time as if the household clock were UTC. East of UTC the reminder came that many hours late - in a
    household two hours ahead of UTC, "one hour before" a 09:00 occurrence ended up an hour after it
    had started; west of UTC it came early by the same amount. Only households whose clock is UTC were
    unaffected, which is why it went unnoticed for so long. The reminder of a whole event and every
    other reminder in Yuvomi were never affected. The same misreading could also make an occurrence
    reminder vanish: an occurrence whose reminder matches the series' is folded back into the series,
    and across a daylight-saving boundary two different lead times looked alike - an hour before a
    summer-time occurrence and two hours before a winter-time one both came out as three. The reminder
    you had set for that one date was deleted without a word and the series default took over. Both
    sides of that comparison now read the same clock. Occurrence reminders written before this fix keep
    their wrong time: they cannot be corrected for you, because nothing in the stored row says which
    time zone and which lead time it was written from, and moving somebody's reminder on a guess is
    worse than leaving it. The edit dialog names such a time honestly instead of hiding it (#1260), and
    saving the reminder again writes it correctly. (#1291)

  • Saving a change to one event of a repeating series now asks which events it is for. Editing an
    event of a series - adding a person, for example - used to change that one event only, unless you
    had spotted the "Applies to" field below the repeat settings, which started on "Only this event".
    The person then showed on that single event, and every other event of the series stayed without
    them: a grey dot, no avatar. The field is gone. Saving now asks "Only this event", "This and
    following" or "Whole series", with none of them picked in advance, and cancelling takes you back to
    the form without saving anything. If nothing was changed, saving simply closes the form. A single
    event, and a series that belongs to a synced or subscribed calendar, save as before, without the
    question. Deleting an event of a series asks the same question with the same three buttons,
    instead of a drop-down. A series that already has a person on one event only can be put right by
    opening one of the events without them, picking the person and choosing "Whole series". Both
    dialogs say which event they are about, above the three buttons: its title and the date of the
    occurrence you opened, on the household's clock. That line is what tells you where "This and
    following" would cut the series, and it matters most when deleting - by then the list or the form
    has already closed, and the question is the only thing on screen. A question
    that has just opened ignores taps and clicks for a third of a second, so a quick second tap
    on Save - or the second click of a double-click on Delete - can no longer answer a question that
    nobody has read yet; on a phone the dialog slides up into that very spot. Forms and sheets you
    opened yourself are unaffected and take your first tap as they always did. The keyboard and screen
    readers are not affected: Enter, Space, Tab and Escape work from the first moment. (#1284)

  • An empty database file no longer starts Yuvomi as an empty instance. If the database file
    existed but had a size of zero, Yuvomi took it for a new database, set it up from scratch and came
    up empty, without a word - usually in the very moment somebody was moving data, where that looks
    as if everything is gone. A new installation has no database file at all, so an empty one is left
    behind by a copy or restore that failed or stopped short, or by a very first start that was
    stopped before it had written anything. Yuvomi now refuses to start, leaves the file as it is and
    says what to do in either case: copy the database again and compare its size and checksum with
    the original, or delete the empty file for a fresh start. A write-ahead log (-wal) lying next to
    an empty file used to be deleted by that start as well; it is now left alone, and the message asks
    you to move it aside before either step, because it belongs to the database that was there before
    and would otherwise be read together with the file you copy back in. The same check covers the
    old file name oikos.db. A missing database file still means a fresh installation, as before.
    Restoring a backup onto an empty file with the command-line helper (scripts/restore-backup.js)
    keeps working, and a write-ahead log next to that file is no longer deleted but kept next to the
    pre-restore copy, where the helper tells you. (#1282)

  • Notes, Contacts and Birthdays no longer offer buttons that a read-only member is not allowed to
    press.
    Where your access to a module is "read", these three pages still carried every writing
    control, and each of them ended in an error message once the form was filled in: on the pinboard
    the pin, the delete button, the tappable checklist and the editor inside the note dialog; in
    Contacts the category manager, the selection mode, the vCard import, the delete entry in each row,
    the delete and edit actions of the detail view and the "n" shortcut; on Birthdays the two buttons
    in each row, the swipe gesture behind them and the import from Contacts. The rule is the one Tasks,
    Calendar and Rewards already follow: something that shows a state stays, as a sign that names the
    state rather than as a greyed-out button that promises a touch doing nothing, and something that
    only acts disappears. A pinned note therefore keeps its pin as a sign, a checklist keeps its ticks
    as readable state, and a note still opens - in a reading view, without an editor. What you can read
    stays complete: phone numbers, mail addresses, the map link and the vCard export in Contacts, and
    name, date, age, countdown, name day and note on a birthday. Birthdays follow your access to the
    Calendar, which is the module they belong to. The import button on that page now asks about both
    modules it touches, because it reads contacts and writes birthdays: it needs you to see Contacts,
    as before, and now also to be allowed to edit the Calendar. (#1265)

  • The "n" shortcut no longer opens a create dialog on a page you may only read. Where your
    access to a module is "read", the create button is hidden, but the keyboard shortcut still pressed
    it: the dialog for a new entry opened anyway, and saving it ended in an error. The shortcut now
    does exactly what the visible button would do, so where there is no button, nothing happens.
    (#1265)

  • The attachment field no longer offers an upload you are not allowed to make. Tasks, budget
    entries, shared expenses and inventory items share one field for attaching documents, and an
    uploaded file is stored in Documents - so whether it works depends on your access to Documents,
    not on the page you are on. Somebody allowed to edit tasks but only to read documents saw the
    upload button, and saving the task ended in an error. With read access to Documents the upload
    button, dropping a file onto the field and the size hint are gone; attachments that are already
    there stay visible and open as before, and linking an existing document still works, because the
    link is saved with the task or entry itself. Without any access to Documents the field is not
    shown, and saving leaves existing attachments untouched. (#1265)

  • Undo after moving ingredients to the shopping list is only offered where it can work. Moving
    the ingredients of a meal or a recipe to the shopping list also works for a member who may only
    read the shopping list, but the undo button next to the message then ended in an error, and the
    "create new list" button that appears when there is no list yet led to a list that could not be
    created. Both change the shopping list, so they now appear only for members who may edit it; the
    message itself still says what happened. (#1265)

  • A module switched off for the whole household no longer sends its reminders. Switching a
    module off under Settings means the household does not have it: it leaves the navigation, and its
    pages send you back to the overview. Only pantry, shift and waste reminders respected that. Task,
    calendar, subscription, inventory, document, cycle and birthday reminders kept arriving - as a
    push notification, on a notification channel and in the in-app list - and tapping one opened a
    page that turned you away. They now stay silent while their module is off. Reminders someone set
    by hand, and the ones a subscription, an inventory item or a document creates when it is saved,
    are held back rather than deleted, because nothing would ever bring them back: once the module is
    switched on again, the ones that fell due in the meantime arrive, as they would after the server
    had been down for a while. Cycle and birthday reminders are worked out from their data, so like
    pantry, shift and waste reminders they are cleared while the module is off and come back by
    themselves once it is on. Birthday reminders follow the Birthdays switch, not the Calendar one,
    although they hang on a calendar entry: switching the calendar off leaves them alone. (#1279)

  • The cycle notification a partner receives names whose period is expected. A member can have a
    partner told ahead of their predicted period. On the in-app list that message named the person,
    but as a push notification or on a notification channel it always fell back to the neutral
    wording, because the delivery looked the person up with a reference it never read. (#1279)

  • A two-finger swipe scrolls the main content on a touchscreen, and pinch-to-zoom works there.
    The main area told the browser it may only be panned vertically, and that setting quietly rules
    out pinch-zoom as well. Chromium treats any scroll that starts with two fingers as a pinch and
    drops it entirely where pinch-zoom is not allowed, so on a touchscreen laptop such as a Chromebook
    a two-finger swipe over the main content did nothing, while the sidebar next to it and the
    touchpad scrolled normally. On phones the same setting stopped pinch-to-zoom in the main area,
    although the app allows zooming everywhere else. The main area, the rows in the overview widgets
    and the toast now allow pinch-zoom alongside vertical panning; one-finger scrolling and swiping a
    toast away work as before. (#1276)

  • The message about an undecryptable backup no longer sends you into a dead end. It used to
    advise setting DB_ENCRYPTION_KEY to the other installation's key and restarting. An instance
    that has a key of its own has its own database encrypted with that key, so after the swap Yuvomi
    does not start at all - and the dialog that gave the advice is out of reach from then on. The
    message now says so and points at the command-line route, which replaces the database file and
    sets the key together, with Yuvomi stopped. An instance with no key of its own still gets the old
    advice, because there it is correct: its plaintext database is encrypted with that key on the next
    start. The restore section on the same settings page now says that a backup from another
    installation needs that installation's key, which it never mentioned. And the error on start-up
    names two things it kept to itself: the way back, and a write-ahead log left over from a different
    database lying next to the file - that alone produces the very same "wrong key" error while the
    key is in fact right, which is what made this take two days to pin down. That last paragraph is
    deliberately conditional: after any stop that was not a clean shutdown a database keeps its own
    log, so its mere presence proves nothing, and deleting it would throw away committed transactions
    without fixing the key. It says so, and where it does apply it asks you to move the file aside
    rather than delete it. (#1267)

  • When Yuvomi cannot read its database at start-up, the message names the actual cause instead of
    always blaming the encryption key.
    Every error on the first read was reported as "Wrong
    encryption key", whatever SQLite had said. Two of them happen with the right key: a copy of the
    database that stopped short, and a data directory Yuvomi is not allowed to write to. An incomplete
    copy is now reported as damaged, with the note that the key does open it and the advice to copy
    the file again and compare its checksum with the original. Any other error names SQLite's own
    error code and says nothing about the key; a permissions problem also says which directory to
    check. The key message itself stops sending the wrong people back: its advice to change the key
    back now applies only to someone who changed the key alone. Someone who replaced the database file
    and the key together - the right way to take over a backup - is told that going back will not
    help, and how to find out which of the two is off: the file's size and checksum against the
    original, and if those match, the exact characters of the key, because an environment file is
    parsed rather than copied - systemd, for one, drops backslashes from an unquoted value, reads a
    quote right after "=" as quoting and trims spaces at both ends. (#1267)

  • Restoring a backup that is damaged or incomplete no longer blames the encryption key. On an
    instance with DB_ENCRYPTION_KEY, every backup the restore dialog could not read was reported as
    one from another installation that this instance's key cannot decrypt, followed by advice about
    taking over such a backup on the command line. A backup of this very instance that was cut short -
    by a download or a copy that stopped early - got the same message, although its key is right. It
    is now reported as damaged or incomplete, with the note that the key does open it, that nothing on
    the instance was changed, and the advice to fetch the backup again and compare its size and
    checksum with the stored original. Any other error names SQLite's own error code and says nothing
    about the key; a file the restore is not allowed to read - for example a backup copied by another
    user and restored with the command-line script - is no longer called encrypted, and the message
    says to check its read permission. A backup written with a different key gets the same message as
    before. (#1283)

  • The task board shows all four of its columns, and each one can be folded away. The board
    draws four columns - open, in progress, done and archived - but the layout only ever placed
    three of them per row, so "Archived" dropped into a second row underneath "Open". A grid row
    takes its height from its tallest cell, which meant the archive was pushed further down the
    page every time a task was completed. It now gets a column of its own on wide screens, and two
    columns per row on narrow ones so the cards stay readable.

    "Done" and "Archived" also grow without limit, because the board deliberately asks for every
    task in every state plus the whole archive, and nothing ages out of it. Each column header is
    now a button that folds its column down to just the header, and it remembers what you folded,
    on this device. The count stays visible on a folded column, so it can still say how much it is
    hiding, and a folded column no longer accepts a dragged card - it is not a place to drop
    something into and then lose sight of. (#1250)

  • A task opened from the overview can now be completed in one step, instead of having to be
    started first.
    The reading view offered a single status button, and it moved the task one stage
    along: an open task could only go to "in progress", and only from there to done. Completing
    something therefore took two rounds - start it, open it again, complete it - and nothing in
    between was visible, because the overview does not show a task's status: the row looked exactly
    the same after the first tap, so the tap seemed to have been swallowed. On a phone this was the
    only route to either action, since the list card hides its inline controls on narrow screens and
    the overview opens this view rather than offering a button of its own. An open task now offers
    Complete and Start side by side, with Complete first. Starting a task is unchanged and still
    there - "in progress" says something about the task, it was just never meant to be a turnstile.
    While one of them is waiting for the server, the other is disabled: with two buttons side by
    side a double tap on a slow connection could otherwise complete a task and then immediately
    undo it, taking the awarded points, the recorded completion and - on a repeating task - the
    next occurrence with it. (#1251)

  • Restoring a backup from another installation now says that it is the encryption key, instead of
    claiming the file is not a database.
    A backup carries the encryption of the instance that wrote
    it, so restoring one on an installation with a different key - or with no key at all, which is
    what happens when the new host generates its own secrets - cannot work until that key is set. All
    SQLite could say about it was "file is not a database", and that is what the restore dialog
    showed: the same sentence it shows for a file that really is damaged. The message now names the
    key, says whether this instance has one set at all, and tells you what to do before trying again -
    and it still says "not a valid database" where the file genuinely is not one, so it cannot send
    the next person looking in the wrong place. (#1267)

  • On an instance without HTTPS, one cookie was issued in a way the browser throws away. The
    setting that decides whether cookies are marked HTTPS-only is off by default, which is right for a
    self-hosted instance reached over plain HTTP. One place read that setting backwards, so on exactly
    those instances the security token was handed out marked HTTPS-only and the browser dropped it.
    It mostly hid behind a retry, surfacing as an occasional refused save rather than as anything
    legible. Nobody has to change a setting; instances that had already turned HTTPS-only on were never
    affected.

  • Around the turn of the month, Budget could show the wrong month for a few hours. When you open
    Budget without picking a month, it picks one for you. That pick followed UTC instead of the
    household's own time zone, so east of UTC the first hours of a new month still showed the old one,
    and west of UTC the last evening of a month already showed the next. The summary and the list below
    it each made the pick separately, so they could even disagree with each other. Both now follow the
    household time zone, the same one the rest of the app uses for what counts as today.

  • Tasks, Calendar and Rewards no longer offer buttons that a read-only member is not allowed to
    press.
    Someone whose access to a module is "read" still saw every control: edit, archive, delete,
    add a subtask, the bulk action bar, dragging a card across the board, swiping a row. The server
    refused each of them correctly, so nothing wrong was ever saved - but the refusal arrived as an
    error message, and ticking a task off looked like it had worked for a moment before the checkbox
    sprang back. What stays is everything that tells you something: the tick mark of a task and of a
    subtask are still there, now as a plain mark that names the state instead of a greyed-out button
    that promises a tap it cannot honour. What goes is everything that only acts, because it says
    nothing the row next to it does not already say - where a task sits on the board is what its column
    is for. Two consequences worth knowing about: a member with read-only access to Rewards can no
    longer ask to redeem their own points, which they could before, because the server declines that
    request too; and a wall tablet is unaffected - the two things it may do, ticking a task off for
    a named person and asking for a reward, are granted to it as named routes rather than as module
    access, and they stay exactly where they were.

  • A reminder switch in the task dialog could only ever fail for some members. This one crosses a module
    boundary, so the read-only entry about buttons does not cover it: Reminders belong to
    the Calendar, not to Tasks, so somebody allowed to edit tasks but only to read the calendar was
    still offered the switch. Saving then stored the task and refused the reminder, and all they saw
    was an error next to a task that had in fact been saved. A reminder that is already set now stays
    visible but locked, so it can still be read off, and saving leaves it exactly as it was. Where
    there is nothing set - a task being created, or one that never had a reminder - the section is
    gone rather than shown as an empty switch that cannot be used, and the same goes for members with
    no calendar access at all. One rule still holds for everyone: a task with a reminder needs a due
    date, so clearing the date is refused while a reminder hangs on the task, and the message names
    the date rather than the switch that cannot be operated. Changing the date to another one is
    fine, and so is saving a task that already arrived without a date - reminders belong to whoever
    set them, so another member may have cleared the date earlier, and being locked out of every
    later edit would be nobody's fault but also nobody's to repair. With write access nothing
    changes.

  • A reminder for a task or an event you deleted no longer goes off afterwards. Deleting an item
    was meant to take its reminders with it, but the clean-up happened in the browser, as a second
    request sent right behind the deletion - and that request was easy to lose. Closing the tab
    straight after deleting dropped it. Deleting through the API or a connected assistant never sent
    it at all. And a member who may change tasks but may only read the calendar had it refused,
    without being told. What stayed behind was a reminder pointing at something that no longer exists:
    it arrived later as a notification with a heading and no text, or sat in the app as an empty line
    waiting to be dismissed. A reminder that somebody else in the household had set on the same task
    outlived it every time, because the browser only ever cleaned up the reminders of whoever did the
    deleting. Deleting now takes the reminders with it on the server, whichever way the item is
    deleted, and reminders left over from before are cleared once when you update.

  • A task reminder that had ended up after the due date was described as being on it. A reminder
    is stored as a point in time, while the dialog offers lead times - "1 day before" and the like. Pull
    a due date forward past a reminder that was already set and there is no lead time left to name, and
    the dialog fell back on "at the due time" for it. So a reminder that would not go off until six days
    after the task was due looked as though it went off with it. Worse, saving the task again believed
    that description and moved the reminder to match it, without being asked. The dialog now names the
    situation instead: the list gets an entry that says the reminder is after the due date, a warning
    beside it spells out when it actually goes off, and saving leaves it exactly where it is. Picking a
    lead time moves it as it always did. Move the due date back past the reminder - the obvious way to
    fix it - and the dialog notices while you are still in it: the entry and the warning give way to the
    lead time that now applies, rather than going on claiming a situation that has passed.

  • A calendar reminder that had ended up after the event's start no longer moves when you save.
    The calendar has the same problem as the task dialog, in its own code. Move an event - by dragging
    it, through a sync, or from another app - past a reminder that was already set, and the edit dialog
    showed that reminder as "Custom, 1 minute" before the start. Saving believed it and moved the
    reminder there, even if you had only changed the title: a reminder set for a week after the event
    jumped to a minute before it. The row now says the reminder is after the event starts, a warning
    beside it spells out when it actually goes off, and saving leaves it exactly where it is, row by
    row, next to any other reminders on the event. Picking a lead time moves it as it always did. Move
    the start in the dialog and the row follows along: once the reminder is before the new start again,
    it shows the lead time that applies, and the reminder itself still stays where it was. For a single
    occurrence of a repeating event, where reminders can only be saved as a lead time, the reminder is
    left untouched as long as you do not change the reminders; if you do, the dialog asks you to pick a
    lead time for it or remove it instead of moving it for you. The event details now also give the
    time of a reminder that has no preset lead time, not just the day. (#1260)

  • An appointment moved to another calendar now belongs to that calendar's person. A calendar you
    subscribe to can have a household member set as its default, and everything arriving from it is
    assigned to that person. Moving an appointment from one such calendar to another sent it back with
    the same identity, so Yuvomi recognised it and updated the row it already had: the detail view then
    named the new calendar, but the assignment stayed with the person of the old one - and with it the
    colour the appointment is drawn in, which comes from whoever it is assigned to. The assignment now
    moves along, for Google, iCloud and CalDAV alike. Only an untouched one does: if you had assigned
    the appointment to somebody else by hand, added a second person, or taken the assignment away, it
    stays exactly as you left it, and a calendar without a default person takes nothing away. Reminders
    follow the assignment as they always have, except that one whose time has already passed is not
    delivered again to the new person. An appointment that carries a colour of its own still shows that
    colour. (#1270)

  • An appointment you wrote yourself and assigned by hand keeps that assignment when it moves
    between calendars.
    The entry above moves an untouched default assignment along with an
    appointment, and it read "untouched" off the assignment naming exactly the default person of the
    calendar the appointment came from. An appointment you wrote in Yuvomi and sent out to a calendar
    looks the same from the inside, because sending it out records which calendar it now lies in: an
    appointment assigned to Anna by hand and sent into Anna's own calendar was in exactly that state,
    and the next move replaced your assignment with the other calendar's person. An appointment Yuvomi
    sent out is now left alone, by the same rule the one-off filling in of default assignees already
    followed - it carries a trace no import has, either the target calendar you picked or the
    identifier Yuvomi uploads it under. Appointments that really did arrive from a calendar are
    unaffected and still take their assignment with them. (#1270)

Security

  • Reading the calendar no longer reaches the contact book, the sync accounts, or the sync targets.
    Permission for the API is granted per module, and the guard judged a request by the first part of
    its path - so a credential that had been given the calendar alone also reached GET /birthdays/import/candidates, which lists every contact with name and birth date, and the status
    routes of the connected CalDAV, Outlook, Google and Apple accounts, which name the server address,
    the user name, the account mail address and the last sync error - error text that comes from the
    other side and regularly carries its address or an account identifier. The birthday-import routes
    now ask for contact access as well, the status routes leave those management details out for anything but a signed-in person, and the two
    sync-target lists - they name the connected accounts and their collection URLs - are limited to
    whoever may actually save to them. If you use an API token scoped to calendar:read or
    tasks:read for an integration that reads one of these, give it contacts:read or write access to
    the module in question. The birthday page stops offering its import button where contacts are out
    of reach. (#1241)

  • A reward request and its wish text now stay between the person asking and whoever decides. The
    list of redemption requests handed every reader of the module up to 300 rows, each with the
    free-form note and the avatar of the member who wrote it; the page showed you only your own, but it
    filtered them after downloading everybody's. Approving and rejecting is an administrator's job, so
    administrators still see all of them and everyone else now gets their own from the query. Nothing
    changes in what the page shows. If you use an API token scoped to rewards:read for an integration
    that reads the whole household's requests, it will now see only those of the member it acts as.
    (#1241)

Don't miss a new yuvomi release

NewReleases is sending notifications on new releases.