Files
duty-teller/docs/import-format.md
Nikolay Tatarinov 9486f7004d
All checks were successful
CI / lint-and-test (push) Successful in 19s
docs: update README and configuration documentation for clarity
- Revised the README to improve clarity in instructions for accessing the calendar miniapp, including changes to the phrasing for consistency.
- Updated the configuration documentation to enhance the description of the `EXTERNAL_CALENDAR_ICS_URL` setting, ensuring users understand its purpose and usage.
- Improved the import format documentation by translating terms to English for better accessibility to a wider audience.
- Enhanced the runbook with clearer instructions regarding access issues when using direct links, emphasizing the importance of using the bot's menu button.
2026-02-20 16:26:47 +03:00

2.7 KiB
Raw Blame History

Duty-schedule import format

The duty-schedule format is used by the /import_duty_schedule command. Only users in ADMIN_USERNAMES or ADMIN_PHONES can import.

Import flow

  1. Handover time — The bot asks for the shift handover time and optional timezone (e.g. 09:00 Europe/Moscow or 06:00 UTC). This is converted to UTC and used as the boundary between duty periods when creating records.
  2. JSON file — Send a file in duty-schedule format (see below). On re-import, duties in the same date range for each user are replaced by the new data.

Format specification

  • meta (required) — Object with:

    • start_date (required) — First day of the schedule, YYYY-MM-DD.
    • weeks (optional) — Not used to limit length; the number of days is derived from the longest duty string (see below).
  • schedule (required) — Array of objects. Each object:

    • name (required) — Full name of the person (string).
    • duty (required) — String of cells separated by ;. Each cell corresponds to one day starting from meta.start_date (first cell = start_date, second = start_date + 1 day, etc.). Empty or whitespace = no event for that day.

Cell values (single character, case-sensitive where noted)

Value Meaning Notes
в, В, б, Б Duty Any of these four
Н Unavailable Exactly Н
О Vacation Exactly О
(empty/space/other) No event Ignored for import

The number of days in the schedule is the maximum length of any duty string when split by ;. If duty is empty or missing, it is treated as an empty list of cells.

Example JSON

{
  "meta": {
    "start_date": "2025-02-01",
    "weeks": 4
  },
  "schedule": [
    {
      "name": "Ivanov Ivan",
      "duty": ";;В;;;Н;;О;;В;;"
    },
    {
      "name": "Petrov Petr",
      "duty": ";;;В;;;;;;В;;;"
    }
  ]
}
  • start_date is 2025-02-01; the longest duty has 14 cells (after splitting by ;), so the schedule spans 14 days (2025-02-01 … 2025-02-14).
  • First person: duty on day index 2 (В), unavailable on 6 (Н), vacation on 8 (О), duty on 11 (В). Other cells are empty.
  • Second person: duty on day indices 3 and 10.

Validation

  • meta and meta.start_date must be present and valid; start_date must parse as YYYY-MM-DD.
  • schedule must be an array; each item must be an object with string name (non-empty after strip) and string duty (if missing, treated as "").
  • Invalid JSON or encoding raises an error; the parser reports missing or invalid fields (see duty_teller.importers.duty_schedule.DutyScheduleParseError).